论坛首页 Java企业应用论坛

ThreadLocal示例

浏览 16626 次
精华帖 (2) :: 良好帖 (13) :: 新手帖 (13) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-09-08  
ThreadLocal 以空间换时间
Synchornized 以时间换空间

ThreadLocal 同一个线程下确保获取的对象是唯一的,对其修改不会影响到其他线程。
其中initialValue()是一个空方法

疑问:
private static ThreadLocal<SimpleDateFormat> threadlocal = new ThreadLocal<SimpleDateFormat>(){
  protected synchronized Object initialValue(){
      reutrn new SimpleDateFormat(format);
  }
};
每个ThreadLocal在多线程下也能确保拿到的对象和其他线程不相同
而上面也提到了ThreadLocal是空间换时间,但是里面覆盖的initialValue() 却又加上了synchornized字段,这是不是有点相互矛盾?

疑问的地方在这,望解答。


0 请登录后投票
   发表时间:2010-09-08  
我觉得效率是否真的有提高?
每个线程第一次调用ThreadLocal的时候会调用initialValue,也就是说其实每个线程还是创建了一个SimpleDateFormat啊
0 请登录后投票
   发表时间:2010-09-08  
最好再使用SoftReference,毕竟有的DateFormat一个线程用一次可能就在也不用了。
0 请登录后投票
   发表时间:2010-09-08  
liujun999999 写道
我觉得效率是否真的有提高?
每个线程第一次调用ThreadLocal的时候会调用initialValue,也就是说其实每个线程还是创建了一个SimpleDateFormat啊


threadlocal.get()的时候会先从一个可以相当于缓存的ThreadLocalMap的类里面获取,如果没有才创建
0 请登录后投票
   发表时间:2010-09-08  
liujun999999 写道
我觉得效率是否真的有提高?
每个线程第一次调用ThreadLocal的时候会调用initialValue,也就是说其实每个线程还是创建了一个SimpleDateFormat啊

呵呵,是static变量,不会每次都调用initialValue,初始化的时候一次而已。
0 请登录后投票
   发表时间:2010-09-08  
分离的北极熊 写道
liujun999999 写道
我觉得效率是否真的有提高?
每个线程第一次调用ThreadLocal的时候会调用initialValue,也就是说其实每个线程还是创建了一个SimpleDateFormat啊


threadlocal.get()的时候会先从一个可以相当于缓存的ThreadLocalMap的类里面获取,如果没有才创建

这个我知道,也就是这个代码保证了一个线程最多只创建一个对象,也有一定的实际意义,学习
0 请登录后投票
   发表时间:2010-09-08   最后修改:2010-09-08
pengzhoushuo 写道

liujun999999 写道
我觉得效率是否真的有提高?
每个线程第一次调用ThreadLocal的时候会调用initialValue,也就是说其实每个线程还是创建了一个SimpleDateFormat啊

呵呵,是static变量,不会每次都调用initialValue,初始化的时候一次而已。

查看ThreadLocal类的doc

引用


protected T initialValue()
返回此线程局部变量的当前线程的“初始值”。线程第一次使用 get() 方法访问变量时将调用此方法,但如果线程之前调用了 set(T) 方法,则不会对该线程再调用 initialValue 方法。通常,此方法对每个线程最多调用一次,但如果在调用 get() 后又调用了 remove(),则可能再次调用此方法。
该实现返回 null;如果程序员希望线程局部变量具有 null 以外的值,则必须为 ThreadLocal 创建子类,并重写此方法。通常将使用匿名内部类完成此操作。

返回:
返回此线程局部变量的初始值

并不是创建ThreadLocal对象的时候调用一次
0 请登录后投票
   发表时间:2010-09-08  
分离的北极熊 写道
ThreadLocal 以空间换时间
Synchornized 以时间换空间

ThreadLocal 同一个线程下确保获取的对象是唯一的,对其修改不会影响到其他线程。
其中initialValue()是一个空方法

疑问:
private static ThreadLocal<SimpleDateFormat> threadlocal = new ThreadLocal<SimpleDateFormat>(){
  protected synchronized Object initialValue(){
      reutrn new SimpleDateFormat(format);
  }
};
每个ThreadLocal在多线程下也能确保拿到的对象和其他线程不相同
而上面也提到了ThreadLocal是空间换时间,但是里面覆盖的initialValue() 却又加上了synchornized字段,这是不是有点相互矛盾?
疑问的地方在这,望解答。

synchornized只会在初始化时使用一次,加锁防止多线程不同步现象出现;
0 请登录后投票
   发表时间:2010-09-08  
niumd 写道
分离的北极熊 写道
ThreadLocal 以空间换时间
Synchornized 以时间换空间

ThreadLocal 同一个线程下确保获取的对象是唯一的,对其修改不会影响到其他线程。
其中initialValue()是一个空方法

疑问:
private static ThreadLocal<SimpleDateFormat> threadlocal = new ThreadLocal<SimpleDateFormat>(){
  protected synchronized Object initialValue(){
      reutrn new SimpleDateFormat(format);
  }
};
每个ThreadLocal在多线程下也能确保拿到的对象和其他线程不相同
而上面也提到了ThreadLocal是空间换时间,但是里面覆盖的initialValue() 却又加上了synchornized字段,这是不是有点相互矛盾?
疑问的地方在这,望解答。

synchornized只会在初始化时使用一次,加锁防止多线程不同步现象出现;


我知道在第一次的时候会return setInitialValue();
ThreadLocal在多线程的情况下,不也是确保每一个线程从ThreadLocal拿到的对象和其他线程从ThreadLocal拿到的对象不同么,而同一个线程下所有的ThreadLocal获取的对象是相同的。

还是不理解加的这个synchronized,源码中的initialValue() 也没有加任何的 同步啊

如果我们用ThreadLocal管理Hibernate的session 或者数据库连接Connection的时候,那都要类似的写法了

但是在换成普通写法的时候,缺没有看到同步synchronized的影子
 public static DateFormat getDateFormat()   
 {  
     DateFormat df = (DateFormat) threadLocal.get();  
     if(df==null){  
         df = new SimpleDateFormat(DATE_FORMAT)  
         threadLocal.set(df);  
     }  
     return df;  
 }  
0 请登录后投票
   发表时间:2010-09-08  
pengjunwu 写道
不明白 如果format 有2种或者更多 怎么处理
String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; 
String DATE_FORMAT = "yyyy/MM/dd HH:mm:ss"; .....

每个一个thread local
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics