一个很奇怪的问题:为什么从threadlocal中取数据的时候是null

callen033 2015-02-06 10:05:05
class MyThreadLocalData3 {
private MyThreadLocalData3() {
}

// 线程共享
private static ThreadLocal<MyThreadLocalData3> threadLocal = new ThreadLocal<MyThreadLocalData3>();

private static MyThreadLocalData3 instance=null;

public static MyThreadLocalData3 getThreadInstance() {
if (instance == null) {
synchronized (threadLocal) {
if (instance == null) {
instance = new MyThreadLocalData3();
threadLocal.set(instance);
}
}
}
return threadLocal.get();

}
}



public class ThreadLocal2 {
public static void main(String[] args) {
final List<MyThreadLocalData3> list=new ArrayList<MyThreadLocalData3>();
MyThreadLocalData3 data1= MyThreadLocalData3.getThreadInstance();
MyThreadLocalData3 data2= MyThreadLocalData3.getThreadInstance();

list.add(data1);
list.add(data2);

new Thread(){

@Override
public void run() {
System.out.println(list.size()); // 2
MyThreadLocalData3 data3= MyThreadLocalData3.getThreadInstance();
list.add(data3);
System.out.println(data3); // data3为什么是 null值???????
System.out.println(list.size()); // 3
}

}.start();
// 主线程睡眠3s,保证子线程执行完毕
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// list里的第一个和第二个是同一个线程里,从threadlocal取到的对象,所以相等
System.out.println(list.get(0) == list.get(1)); // true
// 不同线程里的两个对象
System.out.println(list.get(1) == list.get(2)); // false

System.out.println(list.get(1)); // 有值

System.out.println(list.get(2)); // null??????????????????????????????????????????????

}
}
...全文
3270 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
callen033 2015-03-27
  • 打赏
  • 举报
回复
“ThreadLocal 存在的一个重要的原因是在IOC或依赖注入等不方便的时候用于传参”这句话的意思能详细说明吗??
skgary 2015-02-20
  • 打赏
  • 举报
回复
引用 4 楼 callen033 的回复:
各位前辈,不好意思啊,这几天因为有事出差去了,回复晚了。 看来是我对threadlocal理解错了,看来threadlocal中的值是与set时的线程绑定的,在其他线程中无法取到值。 那么这里我又有一个问题,既然说threadlocal又称之为副本,那么两次从threadlocal中取到的值,应该是不同的啊。还有,threadlocal存在的意义是什么?是否仅仅就是不能再其他线程中取到threadlocal管理的变量?
前面的几个问题你自己去看一下源代码,仔细理解一下就好了。 ThreadLocal 存在的一个重要的原因是在IOC或依赖注入等不方便的时候用于传参
qq_26102779 2015-02-20
  • 打赏
  • 举报
回复
不觉得啊。。。。。。。。。。
callen033 2015-02-14
  • 打赏
  • 举报
回复
各位前辈,不好意思啊,这几天因为有事出差去了,回复晚了。 看来是我对threadlocal理解错了,看来threadlocal中的值是与set时的线程绑定的,在其他线程中无法取到值。 那么这里我又有一个问题,既然说threadlocal又称之为副本,那么两次从threadlocal中取到的值,应该是不同的啊。还有,threadlocal存在的意义是什么?是否仅仅就是不能再其他线程中取到threadlocal管理的变量?
览菊 2015-02-07
  • 打赏
  • 举报
回复
threadLocal.set(instance); 是将值绑定到当前线程中, if (instance == null) 是判断一个在所有线程都是单例的变量。 threadLocal.get; 是在当前线程中取值。 if (instance == null) 只能判断这个单例变量是否有值,不能判断当前线程是否有值!!!
龙四 2015-02-07
  • 打赏
  • 举报
回复
没看问题回答:在设置和取出的时候都打印下Thread.currentThread就知道是不是同一个线程了
skgary 2015-02-07
  • 打赏
  • 举报
回复
问题出在你的单例构造函数里了。 private static MyThreadLocalData3 instance=null; 你把这个申明为static,就是单例模式,那么 if (instance == null) 在第二个线程里是不可能成立的。 但 ThreadLocal里的东西在第二个线程里却是在空的,所以 return threadLocal.get(); 就返回 null了。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧