可以实现资源对象的线程隔离;可以实现了线程内的资源共享
如果使用 ThreadLocal 管理变量,则每一个使用该变量的线程都获得该变量的副本, 副本之间相互独立,这样每一个线程都可以随意修改自己的变量副本,而不会对其他线程产生影响
ThreadLocal() : 创建一个线程本地变量get() : 返回此线程局部变量的当前线程副本中的值initialValue() : 返回此线程局部变量的当前线程的"初始值"set(T value) : 将此线程局部变量的当前线程副本中的值设置为 value例子:四个线程卖10张票
是分别卖10张票
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadTest {
public static void main(String[] args) {
synchronizeThread st = new synchronizeThread();
new Thread(st, "1").start();
new Thread(st, "2").start();
new Thread(st, "3").start();
new Thread(st, "4").start();
}
}
class synchronizeThread implements Runnable {
ThreadLocal<Integer> ticketNumber = new ThreadLocal<Integer>() {//创建实例对象
@Override
protected Integer initialValue() {
return 10;//初始值
}
};
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if (ticketNumber.get() > 0) {//get得到值
System.out.println("线程【" + Thread.currentThread().getName() + "】卖出了一张票,现在剩余了【" + ticketNumber.get() + "】张票");
ticketNumber.set(ticketNumber.get() - 1);//set修改值
} else {
break;
}
}
}
}
原理是为每个线程创建变量副本,不同线程之间不可见,保证线程安全。每个线程内部都维护了一个 ThreadLocalMap,key 为 threadLocal 实例,value 为要保存的副本
使用 ThreadLocal 会存在内存泄露问题,因为 key 为弱引用,而 value 为强引用,每次 GC 时 key 都会回收,而 value 不会被回收,所以一般使用 static 修饰 ThreadLocal,可以随时获取 value。为了解决内存泄漏问题,可以在每次使用完后删除 value