ThreadLocal是什么
该类提供了线程局部变量,为每一个线程创建一个单独的变量副本,使得每个线程都可以独立的改变自己所拥有的变量副本,而不会影响其他线程所对应的副本,消除了竞争条件。
采用的以空间换时间的做法,在每个Thread里维护一个以开地址法实现的ThreadLocal.ThreadLocalMap,把数据隔离
线程本地存储根除了对变量的共享。
提供了四个方法:
- get() 返回此线程局部变量的当前线程副本中的值
- initialValue() 返回此线程局部变量当前线程的初始值,当线程第一次调用get()或set()方法时调用,并且只调用一次
- remove() 移除此线程局部变量当前线程的值
- set(T value) 将此线程局部变量的当前线程副本中的值设置为指定值
- 还有一个静态内部类 ThreadLocalMap 提供了一种用键值对方式存储每一个线程的变量副本的方法,key为当前的ThreadLocal对象,value为对象线程的变量副本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public class MyThread implements Runnable {
@Override public void run() { for (int i = 0; i < 3; i++) { ThreadLocalVariableHolder.increment(); System.out.println(Thread.currentThread().getName() + ":" + ThreadLocalVariableHolder.get()); Thread.yield(); } } }
public class ThreadLocalVariableHolder { private static ThreadLocal<Integer> myThreadLocal = new ThreadLocal<Integer>() { protected Integer initialValue() { return 0; } };
public static void increment() { myThreadLocal.set(myThreadLocal.get() + 1); }
public static int get(){ return myThreadLocal.get(); }
public static void main(String[] args) { ExecutorService executorService = Executors.newCachedThreadPool(); for(int i=0;i<5;i++){ executorService.execute(new MyThread()); } executorService.shutdown(); } }
|
执行结果
pool-1-thread-1:1
pool-1-thread-2:1
pool-1-thread-3:1
pool-1-thread-3:2
pool-1-thread-2:2
pool-1-thread-1:2
pool-1-thread-2:3
pool-1-thread-3:3
pool-1-thread-4:1
pool-1-thread-1:3
pool-1-thread-4:2
pool-1-thread-4:3
pool-1-thread-5:1
pool-1-thread-5:2
pool-1-thread-5:3