ThreadLocal 提供了get与set等访问接口和方法,这些方法为每个使用该变量的线程都存有一份独立的副本,因此get总是返回由当前执行线程在调用set时设置的最新值。
ThreadLocal对象通常用于防止对可变的单实例变量(Singleton)或全局变量进行共享。例如,在单线程应用程序中可能会维持一个全局的数据库连接,并在程序启动时初始化这个连接对象,从而避免在调用每个方法时都要传递一个Connection对象。由于JDBC的连接对象不一定是线程安全的,因此,当多线程应用程序在没有协同的情况下使用全局变量时,就不是线程安全的,代码如下:
private static ThreadLocal<Connection> connectionHolder
= new ThreadLocal<Connection>() {
public Connection initialValue(){
return DriverManager.getConnection(DB_URL);
}
};
public static Connection getConnection(){
return connectionHolder.get();
}
当某个频繁执行的操作需要一个临时对象,例如一个缓冲区,而同时又希望避免在每次执行时都重新分配该临时对象,就可以使用这项技术。例如,在Java5.0之前,Integer.toString()方法使用ThreadLocal对象来保存一个12字节大小的缓冲区,用于对结果进行格式化,而不是使用共享的静态缓冲区(这需要锁机制)或者在每次调用时都分配一个新的缓冲区。
关于ThreadLocal内存泄漏问题,可参考此文http://www.importnew.com/22039.html
InheritableThreadLocal类可以让子线程从父线程中取值。在使用InheritableThreadLocal类需要注意的一点是,如果子线程在取值的同时,主线程对InheritableThreadLocal中的值进行修改,那么子线程取到的值仍是旧值。