0
点赞
收藏
分享

微信扫一扫

Java并发编程之ThreadLocal类详解


ThreadLocal类可以理解为 ThreadLocalVariable (线程局部变量) , 提供了get与set等访问接口或方法,这些方法为每个使用该变量的线程都存有一份独立的副本,因此get总是返回当前执行线程在调用set时设置的最新值。可以将ThreadLocal<T>视为 包含了Map<Thread,T>对象,保存了特定于该线程的值。



概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

模拟ThreadLocal

​​import java.util.Collections;​​


​​import java.util.HashMap;​​


​​import java.util.Map;​​





​​public class SimpleThreadLocal<T> {​​


​​ private Map<Thread, T> valueMap = Collections​​


​​ .synchronizedMap(new HashMap<Thread, T>());​​





​​ public void set(T newValue) {​​


​​ valueMap.put(Thread.currentThread(), newValue); // ①键为线程对象,值为本线程的变量副本​​


​​ }​​





​​ public T get() {​​


​​ Thread currentThread = Thread.currentThread();​​


​​ T o = valueMap.get(currentThread); // ②返回本线程对应的变量​​


​​ if (o == null && !valueMap.containsKey(currentThread)) { // ③如果在Map中不存在,放到Map中保存起来。​​


​​ o = initialValue();​​


​​ valueMap.put(currentThread, o);​​


​​ }​​


​​ return o;​​


​​ }​​





​​ public void remove() {​​


​​ valueMap.remove(Thread.currentThread());​​


​​ }​​





​​ protected T initialValue() {​​


​​ return null;​​


​​ }​​


​​}​​


实用ThreadLocal





​​class Count {​​


​​ private SimpleThreadLocal<Integer> count = new SimpleThreadLocal<Integer>() {​​


​​ @Override​​


​​ protected Integer initialValue() {​​


​​ return 0;​​


​​ }​​


​​ };​​





​​ public Integer increase() {​​


​​ count.set(count.get() + 1);​​


​​ return count.get();​​


​​ }​​





​​}​​





​​class TestThread implements Runnable {​​


​​ private Count count;​​





​​ public TestThread(Count count) {​​


​​ this.count = count;​​


​​ }​​





​​ @Override​​


​​ public void run() {​​


​​ // TODO Auto-generated method stub​​


​​ for (int i = 1; i <= 3; i++) {​​


​​ System.out.println(Thread.currentThread().getName() + "\t" + i​​


​​ + "th\t" + count.increase());​​


​​ }​​


​​ }​​


​​}​​





​​public class TestThreadLocal {​​


​​ public static void main(String[] args) {​​


​​ Count count = new Count();​​


​​ Thread t1 = new Thread(new TestThread(count));​​


​​ Thread t2 = new Thread(new TestThread(count));​​


​​ Thread t3 = new Thread(new TestThread(count));​​


​​ Thread t4 = new Thread(new TestThread(count));​​


​​ t1.start();​​


​​ t2.start();​​


​​ t3.start();​​


​​ t4.start();​​


​​ }​​


​​}​​


​​
​​


输出



Thread-0    1th    1



Thread-0    2th    2



Thread-0    3th    3



Thread-3    1th    1



Thread-1    1th    1



Thread-1    2th    2



Thread-2    1th    1



Thread-1    3th    3



Thread-3    2th    2



Thread-3    3th    3



Thread-2    2th    2


Thread-2    3th    3


举报

相关推荐

0 条评论