一、示例

线程池内的线程并没有父子关系,所以不适合InheritableThreadLocal的使用场景

public class ThreadPoolInheritableThreadLocalDemo {

//    static ThreadLocal<String> threadLocal = new InheritableThreadLocal<>();
// static ExecutorService pool = Executors.newFixedThreadPool(2); static TransmittableThreadLocal<String> threadLocal = new TransmittableThreadLocal<>();
static ExecutorService pool = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(3)); public static void main(String[] args) {
for(int i=0;i<100;i++) {
int j = i;
pool.execute(new Thread(new Runnable() {
@Override
public void run() {
ThreadPoolInheritableThreadLocalDemo.threadLocal.set("superWorld"+j); ThreadPoolInheritableThreadLocalDemo.pool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() +
" : " +
ThreadPoolInheritableThreadLocalDemo.threadLocal.get());
}
});
}
}));
}
} }

二、TransmittableThreadLocal实现分析

读取线程间传递的ThreadLocal 值比较麻烦,ThreadLocal 和 InheritableThreadLocal 都没有开放内部的 ThreadLocalMap,不能直接读取。

所以要么自己完全实现一套 ThreadLocalMap 机制(如 Netty 的 FastThreadLocal),要么就是自己实现 ThreadLocal 的子类,在每次调用 ThreadLocal

的 set/get/remove 等接口的时候,为 Thread 记录到底绑定了哪些需要发生线程间传递的 ThreadLocal 对象。

/**
*实际存储值的工作还是父类ThreadLocal完成
*TransmittableThreadLocal 只是记录了哪些线程使用了TransmittableThreadLocal对象
*/
@Override
public final void set(T value) {
super.set(value);
if (null == value) { // may set null to remove value
removeValue();
} else {
addValue();
}
}/**
*holder 只是为了记录使用了哪些 TransmittableThreadLocal 对象
*在构造TtlRunnable/TtlCallable 的时候, 通过holder取得对应的TransmittableThreadLocal
   *InheritableThreadLocal的默认值是WeakHashMap
*/
private static InheritableThreadLocal<Map<TransmittableThreadLocal<?>, ?>> holder =
new InheritableThreadLocal<Map<TransmittableThreadLocal<?>, ?>>() {
@Override
protected Map<TransmittableThreadLocal<?>, ?> initialValue() {
return new WeakHashMap<TransmittableThreadLocal<?>, Object>();
} @Override
protected Map<TransmittableThreadLocal<?>, ?> childValue(Map<TransmittableThreadLocal<?>, ?> parentValue) {
return new WeakHashMap<TransmittableThreadLocal<?>, Object>(parentValue);
}
}; private void addValue() {
if (!holder.get().containsKey(this)) {
holder.get().put(this, null); // WeakHashMap supports null value.
}
} private void removeValue() {
holder.get().remove(this);
}

调用ThreadPoolInheritableThreadLocalDemo.threadLocal.set("superWorld"+j)时,

holder.get().containskey(this) 为false

2. TtlRunnable

构造TtlRunable时,设置线程对应的Map<TransmittableThreadLocal<?>, Object>>

    private TtlRunnable(Runnable runnable, boolean releaseTtlValueReferenceAfterRun) {
     //
this.copiedRef = new AtomicReference<Map<TransmittableThreadLocal<?>, Object>>(TransmittableThreadLocal.copy());
this.runnable = runnable;
this.releaseTtlValueReferenceAfterRun = releaseTtlValueReferenceAfterRun;
}
TransmittableThreadLocal.copy
    static Map<TransmittableThreadLocal<?>, Object> copy() {
Map<TransmittableThreadLocal<?>, Object> copy = new HashMap<TransmittableThreadLocal<?>, Object>();
for (TransmittableThreadLocal<?> threadLocal : holder.get().keySet()) {
copy.put(threadLocal, threadLocal.copyValue());
}
return copy;
}

3.运行时,备份和恢复Map<TransmittableThreadLocal<?>, Object>

TtlRunnable#run

    @Override
public void run() {
Map<TransmittableThreadLocal<?>, Object> copied = copiedRef.get();
if (copied == null || releaseTtlValueReferenceAfterRun && !copiedRef.compareAndSet(copied, null)) {
throw new IllegalStateException("TTL value reference is released after run!");
} Map<TransmittableThreadLocal<?>, Object> backup = TransmittableThreadLocal.backupAndSetToCopied(copied);
try {
runnable.run();
} finally {
TransmittableThreadLocal.restoreBackup(backup);
}
}

参考:

transmittableThreadLocal

最新文章

  1. VI的一些快捷键
  2. strncpy和memcpy的区别
  3. POJ3041Asteroids(二分图最少顶点覆盖)
  4. Spring REST实践之Spring Boot
  5. transform的2D部分,嗯…就这个标题了。
  6. Salesforce开发者学习笔记之二:Salesforce开发平台应用场景
  7. filebeat.yml(中文配置详解)
  8. 剑指Offer-链表中环的入口结点
  9. UI设计切忌墨守成规,但改变也须用数据说话
  10. lenovo 笔记本ideapad 320c-15改装win7问题
  11. abaqus的umat在vs中debug调试
  12. c# base64编码解码
  13. windows 7 下用git
  14. Editplus中添加System.out.println()快捷键
  15. eclipse Git配置
  16. 欢迎来怼--第三十七次Scrum会议
  17. 05慕课网《进击Node.js基础(一)》HTTP概念进阶(同步/异步)
  18. Java_多线程2_线程池
  19. linux系统中python版本升级
  20. 微信小程序(2)——新建页面

热门文章

  1. RabbitMQ Performance Testing Tool 性能测试工具
  2. Atitit.&#160;Async&#160;await&#160;优缺点&#160;异步编程的原理and实现&#160;java&#160;c#&#160;php
  3. Camera2/HAL3
  4. 基于Python3 + OpenCV3.3.1的远程监控程序
  5. sigaction()之sa_mask
  6. Visual Studio 调试小技巧-从查看窗口得到更多信息(转)
  7. redhat5.8系统学习
  8. 使用nmap 验证多种漏洞
  9. html+css+JavaScript贪吃蛇
  10. 小米Note全网通支持7模19频:先发标准版