【发布时间】:2022-02-03 18:48:45
【问题描述】:
考虑以下代码:
public static void main(String args[]) {
Set<Integer> set=new HashSet<>();
set.add(1);
ThreadLocal<Set> var1=new ThreadLocal<>();
//THREAD1
Runnable r=()->{
var1.set(set);
for(int i=1;i<=10;i++)
System.out.println("Thread ID:"+Thread.currentThread()+": "+var1.get());
};
Thread th=new Thread(r);
th.start();
//THREAD2
Thread th1=new Thread(()-> {
var1.set(set);
var1.get().remove(1); //removing 1 from this thread copy of set.
var1.get().add(2); //adding 2 to this thread copy of set
for(int i=1;i<=10;i++)
System.out.println("Thread ID:"+Thread.currentThread()+": "+var1.get());
});
th1.start();
}
输出:
Thread ID:Thread[Thread-0,5,main]: [2]
Thread ID:Thread[Thread-0,5,main]: [2]
Thread ID:Thread[Thread-0,5,main]: [2]
Thread ID:Thread[Thread-0,5,main]: [2]
Thread ID:Thread[Thread-0,5,main]: [2]
Thread ID:Thread[Thread-0,5,main]: [2]
Thread ID:Thread[Thread-0,5,main]: [2]
Thread ID:Thread[Thread-0,5,main]: [2]
Thread ID:Thread[Thread-0,5,main]: [2]
Thread ID:Thread[Thread-0,5,main]: [2]
Thread ID:Thread[Thread-1,5,main]: [2]
Thread ID:Thread[Thread-1,5,main]: [2]
Thread ID:Thread[Thread-1,5,main]: [2]
Thread ID:Thread[Thread-1,5,main]: [2]
Thread ID:Thread[Thread-1,5,main]: [2]
Thread ID:Thread[Thread-1,5,main]: [2]
Thread ID:Thread[Thread-1,5,main]: [2]
Thread ID:Thread[Thread-1,5,main]: [2]
Thread ID:Thread[Thread-1,5,main]: [2]
Thread ID:Thread[Thread-1,5,main]: [2]
为什么 Thread2 所做的更改(即删除 1 和添加 2)对 thread1 也是可见的?这里的理想用例是什么?
【问题讨论】:
-
ThreadLocal是在子线程启动之前在主线程中创建的,所以只有一个实例。 -
@JimGarrison,应该只有一个
ThreadLocal的实例@ 这就是重点。ThreadLocal<t>实际上是Map<threadID,t>,其中get()和set(v)方法使用调用者的线程 ID 作为键。
标签: java multithreading thread-safety