ThreadLocal 变量和 与线程池配合使用时可能会出现的问题
生活随笔
收集整理的这篇文章主要介绍了
ThreadLocal 变量和 与线程池配合使用时可能会出现的问题
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
ThreadLocal 变量和 与线程池配合使用时可能会出现的问题
ThreadLocal 的介绍和使用
先看下ThreadLocal变量的使用
public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);} //获取Thread类里面的 ThreadLocalMap 变量ThreadLocalMap getMap(Thread t) {return t.threadLocals;}public T get() {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {ThreadLocalMap.Entry e = map.getEntry(this);if (e != null) {@SuppressWarnings("unchecked")T result = (T)e.value;return result;}}return setInitialValue();}可以看出来,ThreadLocal就是在每个线程 Thread 类里的变量 ThreadLocalMap。
而ThreadLocalMap 这个Map和HashMap类似。
从这可以看出来,ThreadLocal 中有一个在每个线程中不一样的Map(因为是Thread类的成员变量),所以实现了一个多个线程隔离的数据集。
线程池的回顾
线程池的实现中,启动的工作线程如果有工作会一直工作,直到workQueue中的数据没有,并且超过了pollingTime才会销毁这个工作线程。
两者结合的问题
所以在使用线程池的时候再使用 ThreadLocal 变量就会有一个,同一个工作线程执行不同的任务时,ThreadLocal变量就会有脏读的现象。来看一个例子:
public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(2);final ThreadLocal<String> threadLocal = new ThreadLocal<String>();Runnable runnable = new Runnable() {public void run() {System.out.println(threadLocal.get() == null);threadLocal.set(Thread.currentThread().getName()+": name");}};executorService.submit(runnable);executorService.submit(runnable);executorService.submit(runnable);executorService.submit(runnable);executorService.submit(runnable);executorService.submit(runnable);executorService.shutdown();}console中打印的数据:
true true false false false false结论
由上面的console中打印的数据可以看出来,在提交后面几个任务的时候 threadLocal都不是空值了。即说明
线程池中多个任务可能会使用同一个 ThreadLocal,原因是线程池可能会使用公用的线程来执行任务
总结
以上是生活随笔为你收集整理的ThreadLocal 变量和 与线程池配合使用时可能会出现的问题的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: JAVA垃圾回收的几点知识
- 下一篇: Base64 加密算法原理