用途
本地线程,通常用于防止对可变的单实例对象或全局变量进行共享,常见的比如数据库连接。可以将 ThreadLocal<T> 视为 Map<Thread,T>,虽然实际上并不是这样实现的。也可以把事务上下文保存在 ThreadLocal 中,虽然方便处理一些功能,但是隐性增加了耦合度,降低了代码的可重用性,因此尽量避免滥用 ThreadLocal。ThreadLocal 提供了 get 和 set 常用的方法,set 是用来设置值,get 是用来获取 set 设置的最新的值。这些值相对于使用改变量的线程存有的一份独立的副本。
例子
public class NotSafeDemo2 {private ThreadLocal<Integer> num = new ThreadLocal<>();
public void add(int value) {
try {if (null == num.get()) {num.set(0);
}
int temp = num.get();
num.set(num.get() + value);
Thread.sleep(100);
System.out.println(value + "+" + temp + "=" + num.get());
} catch (InterruptedException e) {e.printStackTrace();
}
}
public static void main(String[] args) {NotSafeDemo2 synchronizeDemo = new NotSafeDemo2();
AddThread3 addThread3 = new AddThread3(synchronizeDemo);
AddThread4 addThread4 = new AddThread4(synchronizeDemo);
addThread3.start();
addThread4.start();}
}
class AddThread3 extends Thread {
NotSafeDemo2 synchronizeDemo;
public AddThread3(NotSafeDemo2 synchronizeDemo) {this.synchronizeDemo = synchronizeDemo;}
@Override
public void run() {synchronizeDemo.add(1);
}
}
class AddThread4 extends Thread {
NotSafeDemo2 synchronizeDemo;
public AddThread4(NotSafeDemo2 synchronizeDemo) {this.synchronizeDemo = synchronizeDemo;}
@Override
public void run() {synchronizeDemo.add(2);
}
}
运行结果如下:
这里直接更改 java 并发编程学习之 synchronize(一)的例子,可以看到,num 的值不被线程共享。