用途

本地线程,通常用于防止对可变的单实例对象或全局变量进行共享,常见的比如数据库连接。可以将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的值不被线程共享。