当前位置: 首页 > wzjs >正文

不用购买域名做网站上海百度推广排名

不用购买域名做网站,上海百度推广排名,长沙做一个网站多少钱,自动建站网站系统域名一、ThreadLocal与InheritableThreadLocal回顾 在介绍TransmittableThreadLocal之前,我们先回顾一下Java中的ThreadLocal和InheritableThreadLocal。 1. ThreadLocal ThreadLocal提供了线程局部变量,每个线程都可以通过get/set访问自己独立的变量副本…
 一、ThreadLocal与InheritableThreadLocal回顾

在介绍TransmittableThreadLocal之前,我们先回顾一下Java中的ThreadLocal和InheritableThreadLocal。

1. ThreadLocal

ThreadLocal提供了线程局部变量,每个线程都可以通过get/set访问自己独立的变量副本。

ThreadLocal<String> threadLocal = new ThreadLocal<>();
threadLocal.set("main thread value");new Thread(() -> {System.out.println(threadLocal.get()); // 输出null
}).start();
2. InheritableThreadLocal

InheritableThreadLocal可以解决父子线程间值传递的问题:```java

InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>();
inheritableThreadLocal.set("main thread value");new Thread(() -> {System.out.println(inheritableThreadLocal.get()); // 输出"main thread value"
}).start();

但是InheritableThreadLocal有局限性:
- 只支持创建新线程时的值传递
- 线程池场景下不适用(线程复用)

 二、TransmittableThreadLocal介绍

TransmittableThreadLocal(TTL)是阿里开源的一个线程间数据传递解决方案,解决了InheritableThreadLocal在线程池场景下的问题。

核心特性
- 支持线程池场景下的值传递
- 支持任务执行前的自定义逻辑
- 支持任务执行后的自定义逻辑
- 兼容InheritableThreadLocal

三、TransmittableThreadLocal原理
1. 核心类结构

- `TransmittableThreadLocal`:继承自InheritableThreadLocal
- `TtlRunnable`/`TtlCallable`:装饰器模式包装Runnable和Callable
- `Transmitter`:提供capture/replay/restore机制

2. 工作原理

TTL的核心思想是"捕获-传递-恢复":

1. 捕获(Capture):在任务提交到线程池时,捕获当前线程的所有TTL变量
2. 传递(Transmit):将捕获的值传递给线程池中的线程
3. 恢复(Replay):线程池中的线程在执行任务前,将TTL值恢复
4. 回滚(Restore):任务执行完成后,恢复线程原来的TTL值

3. 实现机制
// 伪代码展示TTL工作原理
public class TtlRunnable implements Runnable {private final Runnable runnable;private final Object captured;public TtlRunnable(Runnable runnable) {this.runnable = runnable;this.captured = TransmittableThreadLocal.Transmitter.capture();}public void run() {Object backup = TransmittableThreadLocal.Transmitter.replay(captured);try {runnable.run();} finally {TransmittableThreadLocal.Transmitter.restore(backup);}}
}
四、使用方式与示例
1. 基本使用
// 1. 创建TransmittableThreadLocal变量
TransmittableThreadLocal<String> context = new TransmittableThreadLocal<>();// 2. 设置值
context.set("value-set-in-parent");// 3. 包装Runnable/Callable
Runnable task = () -> {System.out.println("获取TTL值: " + context.get());
};
Runnable ttlTask = TtlRunnable.get(task);// 4. 提交到线程池
ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(ttlTask);
executor.shutdown();
2. 线程池集成

更优雅的方式是使用TtlExecutors包装线程池:

ExecutorService executorService = Executors.newCachedThreadPool();
// 包装线程池
ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(executorService);TransmittableThreadLocal<String> context = new TransmittableThreadLocal<>();context.set("value-set-in-parent");ttlExecutorService.execute(() -> {// 可以获取到父线程设置的上下文System.out.println(context.get());
});
3. 异步场景示例
// 初始化TTL上下文
TransmittableThreadLocal<String> requestId = new TransmittableThreadLocal<>();
TransmittableThreadLocal<User> userInfo = new TransmittableThreadLocal<>();// 设置值
requestId.set("REQ-123456");
userInfo.set(new User("张三", "admin"));// 异步处理
CompletableFuture.runAsync(() -> {System.out.println("异步任务中获取requestId: " + requestId.get());System.out.println("异步任务中获取userInfo: " + userInfo.get());},TtlExecutors.getTtlExecutorService(ForkJoinPool.commonPool())
).join();
五、使用经验与最佳实践
1. 初始化建议
// 推荐使用withInitial初始化
private static final TransmittableThreadLocal<SimpleDateFormat> DATE_FORMATTER = TransmittableThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
2. 内存管理

- 及时remove:任务完成后调用remove()避免内存泄漏
- 避免存储大对象:TTL变量应保持轻量级

try {// 使用TTL
} finally {ttlVariable.remove();
}
3. 与线程池配合
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(5);
// 包装线程池
ExecutorService ttlExecutor = TtlExecutors.getTtlExecutorService(executor);// 使用包装后的线程池
ttlExecutor.execute(() -> {// 可以获取TTL值
});
4. 性能考虑

- TTL会带来一定的性能开销(约5%)
- 高并发场景下应评估是否必要
- 考虑使用更轻量的解决方案(如方法参数传递)

六、常见问题与避坑指南
1. 内存泄漏

问题表现:线程池中的线程长期存活,TTL变量一直存在

解决方案:
 

try {// 业务代码
} finally {ttlVariable.remove();
}
2. 线程池未包装

问题表现:直接使用线程池提交任务,TTL值丢失

错误示例:
 

executor.execute(task); // 直接提交,TTL失效

正确做法:

executor.execute(TtlRunnable.get(task)); // 包装后提交
// 或
ttlExecutor.execute(task);
3. 与第三方框架集成

问题表现:Spring的@Async、Hystrix等框架中TTL失效

解决方案:
- 自定义线程池包装器
- 使用AOP拦截增强

@Bean
public Executor asyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();// 配置executorreturn TtlExecutors.getTtlExecutorService(executor.getThreadPoolExecutor());
}
4. 值覆盖问题

问题表现:多个任务共享线程时,TTL值被覆盖

解决方案:
- 确保每次任务执行后恢复原值(TTL已自动处理)
- 避免在任务中修改TTL值影响其他任务

七、适用场景
1. 分布式跟踪
// 设置traceId
TransmittableThreadLocal<String> traceId = new TransmittableThreadLocal<>();void processRequest(Request request) {traceId.set(request.getTraceId());// 异步处理不影响traceId传递asyncService.process(request);
}
2. 用户上下文传递
class UserContextHolder {private static final TransmittableThreadLocal<User> CURRENT_USER = new TransmittableThreadLocal<>();public static void set(User user) {CURRENT_USER.set(user);}public static User get() {return CURRENT_USER.get();}public static void clear() {CURRENT_USER.remove();}
}
3. 多租户系统
// 租户上下文
public class TenantContext {private static final TransmittableThreadLocal<String> TENANT_ID = new TransmittableThreadLocal<>();public static void setTenantId(String tenantId) {TENANT_ID.set(tenantId);}public static String getTenantId() {return TENANT_ID.get();}
}// 业务代码中无需显式传递tenantId
public void businessMethod() {String tenantId = TenantContext.getTenantId();// 使用tenantId
}
4. 日志增强
// 日志上下文
public class LogContext {private static final TransmittableThreadLocal<Map<String, String>> LOG_CONTEXT = TransmittableThreadLocal.withInitial(HashMap::new);public static void put(String key, String value) {LOG_CONTEXT.get().put(key, value);}public static Map<String, String> getContext() {return new HashMap<>(LOG_CONTEXT.get());}
}// 日志切面
@Aspect
@Component
public class LogAspect {@Around("execution(* com.example..*.*(..))")public Object around(ProceedingJoinPoint pjp) throws Throwable {MDC.setContextMap(LogContext.getContext());try {return pjp.proceed();} finally {MDC.clear();}}
}
八、性能优化建议

1. 减少TTL变量数量:只将必要的数据放入TTL
2. 使用基本类型:避免复杂对象
3. 对象复用:对于频繁使用的对象,考虑对象池
4. 合理使用remove:长时间存活的线程池要定期清理

九、与其他技术对比
特性ThreadLocalInheritableThreadLocalTransmittableThreadLocal
线程隔离支持支持支持
父子线程传递不支持支持支持
线程池支持不支持不支持支持
执行前后自定义逻辑不支持不支持支持
性能开销中高
十、总结

TransmittableThreadLocal是解决线程池环境下上下文传递的强大工具,合理使用可以简化编程模型,但需要注意内存管理和性能影响。关键点:

1. 理解"捕获-传递-恢复"机制
2. 线程池必须通过TtlRunnable/TtlCallable或TtlExecutors包装
3. 及时清理避免内存泄漏
4. 评估性能影响,避免滥用

http://www.dtcms.com/wzjs/439102.html

相关文章:

  • 建什么类型个人网站比较好国家提供的免费网课平台
  • 777fj做最好的网站独立站建站平台有哪些
  • 上海做网站的如何免费找精准客户
  • 怎样做视频播放网站长沙网红打卡景点排行榜
  • 六种常见网络营销方法优化大师专业版
  • 做网站可以用中文域名备案嘛海淀区seo引擎优化
  • java wap网站开发教程搜索引擎营销推广方案
  • 重庆网站有哪些永久域名查询
  • 商城建设方案大连seo按天付费
  • 网站建设的秘诀比较好的搜索引擎
  • 南京网站制作公司招聘seo是什么工作
  • 网络加速器下载上海企业优化
  • 网站建设 北京昌平视频运营管理平台
  • 现在有专业做海鲜的网站没有营销托管全网营销推广
  • 网站要怎样做才能获得市场份额外贸网站制作
  • 现在做网站建设的公司多么最新app推广
  • 江苏建设工程监督合肥百度seo代理
  • 湖南网站建设欧黎明seo网站推广方案
  • 大连网站seoseo关键词找29火星软件
  • 邯郸市设计公司电话网站建设seo
  • 电子商务网站建设的风险分析网站优化包括哪些内容
  • 没有域名如何访问网站店铺推广渠道有哪些
  • 设计网站界面软文营销的五大注意事项
  • 模板网站没有源代码站长工具查询系统
  • 网站技术开发文档模板怎么提交百度收录
  • 郑州网站制作价格seo技术培训岳阳
  • 口碑好的秦皇岛网站建设价格百度识图 上传图片
  • 凤凰县政府网站建设嘉兴seo排名外包
  • 北京网站备案要求吗百度怎样发布信息
  • 网站吸引流量的方法qq推广引流怎么做