问题描述
- Java中线程的问题:明明是同一个thread对象,但是threadLocal不是同一个
-
package hub;
/*为啥不同线程中的ThreadLocal是互相独立的。 明明是同一个thread对象- 打印出来的结果 在主线程里面是var2 ,在thread线程中是var1
*/
public class ThreadLocalUsage extends Thread {
public User user = new User();public User getUser() {
return user;
}@Override
public void run() {
this.user.set("var1");while (true) { try { sleep(1000); } catch (InterruptedException e) { } System.out.println(this.user.get()); }
}
public static void main(String[] args) {
ThreadLocalUsage thread = new ThreadLocalUsage(); thread.start(); try { sleep(4000); } catch (InterruptedException e) { } thread.user.set("var2"); System.out.println(thread.user.get());
}
}
class User {
private static ThreadLocal<Object> enclosure = new ThreadLocal<Object>(); // is it must be static? public void set(Object object) { enclosure.set(object); } public Object get() { return enclosure.get(); }
}
上面这个代码明明是一个thread对象,怎么打印出来的threadlocal的值不一样,也就是代表不是同一个threadlocal
- 打印出来的结果 在主线程里面是var2 ,在thread线程中是var1
解决方案
ThreadLocal对象本质类似一个以线程对象为key的哈希表,它能使线程中的某个值与保存值的线程对象关联起来。
所以上述你是两个线程中分别调用了同一个ThreadLocal对象的set方法,所以get方法返回的是当前线程set的值。各个线程中的get的值对应其set的值,所以结果是:
Thread-0:var1
main:var2
Thread-0:var1
两个线程取到的get值各是各的,当然是两个值了。
解决方案二:
你理解错了,不是同一个thread对象,而是同一个ThreadLocal enclosure对象,即thread.user.enclosure对象。
你是两个线程中分别set到ThreadLocal对象的key是某个线程,值是线程设置的值。
你可以打印当前线程+线程设置的值,可以看到你的代码中有两个线程对象main和ThreadLocalUsage两个线程,它们存储在同一个ThreadLocal变量中。修正测试代码如下:
public void run() {
this.user.set("var1");
while (true) {
try {
sleep(1000);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName()+":"+this.user.get());
}
}
public static void main(String[] args) {
ThreadLocalUsage thread = new ThreadLocalUsage();
thread.start();
try {
sleep(4000);
} catch (InterruptedException e) {
}
thread.user.set("var2");
System.out.println(Thread.currentThread().getName()+":"+thread.user.get());
}
测试就可以看到这是两个不同线程的值。
解决方案三:
ThreadLocalUsage thread = new ThreadLocalUsage();
thread.start();
这个地方是这个线程启动的地方
thread.user.set("var2"); 这边是对这个现场的user变量设置值,这个不是应该是同一个线程对象吗