当前位置:   article > 正文

ThreadLocal类_维持线程封闭性的一种更规范方法是使用threadlocal,这个类能使线程中的某个值与保

维持线程封闭性的一种更规范方法是使用threadlocal,这个类能使线程中的某个值与保
维持线程封闭性的一种更规范方法是使用ThreadLocal,这个类能使线程中的某个值与保存值的对象关联起来。
ThreadLocal提供了get和set等访问借口或方法,这些方法为每个使用该变量的线程都存有一份独立的副本,因此get总是返回由当前执


行线程在调用set时设置的最新值。
ThreadLocal对象通常用于防止对可变的单实例变量或全局变量进行共享。例如,在单线程应用程序中可能会维持一个全局的数据库连接


,并在程序自动启动时初始化这个连接对象,从而避免在调用每个方法时都要传递一个Connection对象。由于JDBC的连接对象不一定是线程安全


的,因此,当多线程应用程序在没有协同的情况下使用全局变量时,就不是线程安全的。通过将JDBC的连接保存到ThreadLocal对象中,每个线程


都会拥有属于自己的连接,如下代码所示:
使用ThreadLocal来维持线程封闭性
  1. private static ThreadLocal<Connection> connectionHolder
  2. =new ThreadLocal<Connection>(){
  3. public Connection initialVlaue(){
  4. return DriverManager.getConnection(DB_URL);
  5. }
  6. }
  7. public static Connection getConnection(){
  8. return connectionHolder.get();
  9. }


当某个频繁执行的操作需要一个临时对象,或者一个缓冲区,而同时又希望避免在每次执行时都重新分配该临时对象,就可以使用这项


技术。
例如,在Java5.0之前,Integer.toString()方法使用ThreadLocal对象来保存一个12字节大小的缓冲区,用于对结果进行格式化,而不


是使用共享的静态缓冲区(这需要使用锁机制)或者在每次调用时都分配一个新的缓冲区。
当某个线程初次调用ThreadLocal.get方法时,就会调用initialValue来获得初始值。从概念上看,你可以将ThreadLocal<T>视为包含了


Map<Thread,T>对象,其中保存了特定于该线程的值,但ThreadLocal的实现并非如此。这些特定于线程的值保存在Thread对象中,当线程终止后


,这些值会作为垃圾回收。
假设你需要将一个单线程应用程序移植到多线程环境中,通过将共享的全局变量转换为ThreadLocal对象(如果全局变量的语义允许),


可以维持线程安全性。然而,如果将应用程序范围内的缓存转换为线程局部的缓存,就不会有太大作用。
在实现应用程序框架时大量使用了ThreadLocal。例如,在EJB调用期间,J2EE容器需要将一个事物上下文(Transaction Context)与某


个执行中的线程关联起来。通过将事物上下文保存在静态的ThreadLocal对象中,可以很容易地实现这个功能:当框架代码需要判断当前运行的是


哪个事物时,只需从这个ThreadLocal对象中读取事物上下文。这种机制很方便,因为它避免了在调用每个方法时都要传递执行上下文信息,然而


这也将使用该机制的代码与框架耦合在一起。
开发人员经常滥用ThreadLocal,例如将所有全局变量都作为ThreadLocal对象,或者作为一种“隐藏”方法参数的手段。ThreadLocal变


量类似于全局变量,它能降低代码的可重用性,并在类之间引入隐含的耦合性,因此在使用时要格外小心。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/949065
推荐阅读
相关标签
  

闽ICP备14008679号