欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

ThreadLocal 变量和 与线程池配合使用时可能会出现的问题

发布时间:2024/9/30 编程问答 46 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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 变量和 与线程池配合使用时可能会出现的问题的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。