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

坪山商城网站建设哪家公司靠谱seo是谁

坪山商城网站建设哪家公司靠谱,seo是谁,什么网站是专门做评论赚钱的,烟台有没有做网站前言 ThreadLocal在上下文的数据传输上非常的方便和简洁。工业实践中,比较常用的有三个,ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal,那么他们三个之间有什么区别呢? 常见的三种ThreadLocal比较 ThreadLoc…

前言

ThreadLocal在上下文的数据传输上非常的方便和简洁。工业实践中,比较常用的有三个,ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal,那么他们三个之间有什么区别呢?

常见的三种ThreadLocal比较

ThreadLocalInheritableThreadLocalTransmittableThreadLocal
来源jdkjdk阿里开源
单线程数据传输支持支持支持
new线程数据传输不支持支持支持
线程池数据传输不支持部分支持【简单场景】支持

针对线程池的数据传输,InheritableThreadLocal仅仅能在一些简单场景下做到,下面就用一个案例来说明

先看下线程工厂的定义

package com.tml.mouseDemo.core.threadLocalDemo;import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;public class SimpleThreadFactory implements ThreadFactory {private static AtomicInteger atomicInteger = new AtomicInteger(1);@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r);t.setName("tml-"+atomicInteger.getAndIncrement());return t;}
}

 InheritableThreadLocal部分支持的案例

package com.tml.mouseDemo.core.threadLocalDemo;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadLocalDemo1 {private static ThreadLocal<String> threadLocal = new InheritableThreadLocal<>();private static ExecutorService service = Executors.newFixedThreadPool(2, new SimpleThreadFactory());public static void main(String[] args) throws InterruptedException {threadLocal.set("hello main");for (int i = 0; i < 2; i++) {service.execute(() -> {String s = threadLocal.get();ThreadUtils.printLog("get data " + s);});}//修改threadLocal中的值threadLocal.set("hello world");Thread.sleep(2000);for (int i = 0; i < 2; i++) {service.execute(() -> {String s = threadLocal.get();ThreadUtils.printLog("get data " + s);});}ThreadUtils.printLog("get data " + threadLocal.get());service.shutdown();}
}

运行结果如下 

2025-01-10 19:41:50 | INFO  | tml-1 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello main
2025-01-10 19:41:50 | INFO  | tml-2 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello main
2025-01-10 19:41:52 | INFO  | tml-2 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello main
2025-01-10 19:41:52 | INFO  | main | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello world
2025-01-10 19:41:52 | INFO  | tml-1 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello main

从运行结果来看,前面的两次循环提交的任务,在子线程中确实是能正常的获取主线程设置的变量,即hello main,但是紧接着,我修改了主线程上绑定的变量为hello world,然后继续循环两次提交两个任务,这个时候子线程中获取的线程变量依然是hello main,这明显是与是期望不一致的。

从这个层面来讲,InheritableThreadLocal确实在线程池的层面支持不够友好,可以说仅支持部分简单场景。

根本原因就死线程池的池化机制,从上面的运行日志上也可以看出,提交了4个任务执行的线程依然是两个。线程池中的线程是复用的,InheritableThreadLocal是在创建子线程的时候,会将主线程上绑定的数据拷贝过来,如果我不创建新的线程,但是主线程上绑定的数据改变了呢?那我依然还是读取到之前拷贝的数据。

这个就是InheritableThreadLocal的短板。针对这个问题,阿里开源的TransmittableThreadLocal就能顺利丝滑的解决这个问题。

TransmittableThreadLocal实践

maven依赖

<dependency><groupId>com.alibaba</groupId><artifactId>transmittable-thread-local</artifactId><version>2.12.4</version>
</dependency>

装饰Runnable任务

直接看代码

package com.tml.mouseDemo.core.threadLocalDemo;import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.TtlRunnable;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadLocalDemo1 {private static ThreadLocal<String> threadLocal = new TransmittableThreadLocal<>();private static ExecutorService service = Executors.newFixedThreadPool(2, new SimpleThreadFactory());public static void main(String[] args) throws InterruptedException {threadLocal.set("hello main");for (int i = 0; i < 2; i++) {service.execute(TtlRunnable.get(() -> {String s = threadLocal.get();ThreadUtils.printLog("get data " + s);}));}//修改threadLocal中的值threadLocal.set("hello world");Thread.sleep(2000);for (int i = 0; i < 2; i++) {service.execute(TtlRunnable.get(() -> {String s = threadLocal.get();ThreadUtils.printLog("get data " + s);}));}ThreadUtils.printLog("get data " + threadLocal.get());service.shutdown();}
}

运行结果如下:

 2025-01-10 19:57:03 | INFO  | tml-2 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello main
2025-01-10 19:57:03 | INFO  | tml-1 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello main
2025-01-10 19:57:05 | INFO  | tml-1 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello world
2025-01-10 19:57:05 | INFO  | main | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello world
2025-01-10 19:57:05 | INFO  | tml-2 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello world

与第一个案例的差异点在于,使用了

public static TtlRunnable get(@Nullable Runnable runnable) {return get(runnable, false, false);
}

 来增强了了Runnable任务,执行的结果也是符合预期。

装饰线程池

直接看代码

package com.tml.mouseDemo.core.threadLocalDemo;import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.TtlRunnable;
import com.alibaba.ttl.threadpool.TtlExecutors;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadLocalDemo1 {private static ThreadLocal<String> threadLocal = new TransmittableThreadLocal<>();private static ExecutorService service = Executors.newFixedThreadPool(2, new SimpleThreadFactory());private static ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(service);public static void main(String[] args) throws InterruptedException {threadLocal.set("hello main");for (int i = 0; i < 2; i++) {ttlExecutorService.execute(() -> {String s = threadLocal.get();ThreadUtils.printLog("get data " + s);});}//修改threadLocal中的值threadLocal.set("hello world");Thread.sleep(2000);for (int i = 0; i < 2; i++) {ttlExecutorService.execute(() -> {String s = threadLocal.get();ThreadUtils.printLog("get data " + s);});}ThreadUtils.printLog("get data " + threadLocal.get());service.shutdown();}
}

 运行结果如下

2025-01-10 20:05:05 | INFO  | tml-2 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello main
2025-01-10 20:05:05 | INFO  | tml-1 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello main
2025-01-10 20:05:07 | INFO  | tml-2 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello world
2025-01-10 20:05:07 | INFO  | main | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello world
2025-01-10 20:05:07 | INFO  | tml-1 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello world

与上一个案例的差异点在于,这里没有包装Runnable任务,而是包装了线程池,使用了

public static ExecutorService getTtlExecutorService(@Nullable ExecutorService executorService) {if (TtlAgent.isTtlAgentLoaded() || executorService == null || executorService instanceof TtlEnhanced) {return executorService;}return new ExecutorServiceTtlWrapper(executorService, true);
}

包装了ExecutorService,执行结果也是符合预期

使用java Agent无侵入增强线程池

直接看代码

package com.tml.mouseDemo.core.threadLocalDemo;import com.alibaba.ttl.TransmittableThreadLocal;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadLocalDemo1 {private static ThreadLocal<String> threadLocal = new TransmittableThreadLocal<>();private static ExecutorService service = Executors.newFixedThreadPool(2, new SimpleThreadFactory());public static void main(String[] args) throws InterruptedException {threadLocal.set("hello main");for (int i = 0; i < 2; i++) {service.execute(() -> {String s = threadLocal.get();ThreadUtils.printLog("get data " + s);});}//修改threadLocal中的值threadLocal.set("hello world");Thread.sleep(2000);for (int i = 0; i < 2; i++) {service.execute(() -> {String s = threadLocal.get();ThreadUtils.printLog("get data " + s);});}ThreadUtils.printLog("get data " + threadLocal.get());service.shutdown();}
}

 项目运行的时候,需要添加额外的jvm启动参数,如下

运行结果如下,也是符合预期

 2025-01-10 20:11:59 | INFO  | tml-2 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello main
2025-01-10 20:11:59 | INFO  | tml-1 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello main
2025-01-10 20:12:01 | INFO  | tml-2 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello world
2025-01-10 20:12:01 | INFO  | main | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello world
2025-01-10 20:12:01 | INFO  | tml-1 | com.tml.mouseDemo.core.threadLocalDemo.ThreadUtils | get data hello world

总结

阿里巴巴的TransmittableThreadLocal是继承自InheritableThreadLocal,对他的功能进行了增强,增强的点也主要是在线程池的支持上。

通过上面的三个案例,可以看到TransmittableThreadLocal是非常灵活的,大家可以根据自己的需要,选择对应的方式来实现。

TransmittableThreadLocal的官网GitCode - 全球开发者的开源社区,开源代码托管平台

http://www.ds6.com.cn/news/2168.html

相关文章:

  • 为什么网站百度搜不到了电商平台开发
  • 扬州学做网站培训多少钱推广方案如何写
  • 户外网站做百度网址大全旧版安装
  • 新网站怎么做网络推广华与华营销策划公司
  • 管理咨询公司有哪些长沙seo关键词
  • 日照有做渔家网站的吗品牌推广策划书范文案例
  • vps 同时wordpress vpn搜索引擎优化的目的是
  • 福州绿光网站建设工作室网络营销课程设计
  • 做网站哪家便宜厦门便宜的seo官网优化
  • 如何做销售直播网站怎么在百度上发帖推广
  • 青岛网站优化排名无锡seo公司
  • 网站推广优化建设免费软文推广平台都有哪些
  • 湖南网站建设深圳电子网络推广查询
  • 杭州做网站 做小程序外贸seo优化公司
  • 做网站哪家便宜有哪些平台可以做推广
  • 微信网站怎么做的好汕头seo收费
  • 哪个网站可以帮忙做简历销售营销方案100例
  • 网站 信用卡支付接口潍坊网站建设
  • 网站建设茶店网海南乐秀同城群软件下载
  • 在微信上做彩票网站站长工具怎么用
  • 男人和男人做爰漫画网站深圳谷歌seo推广
  • 手机建设网站南宁优化推广服务
  • 新产品线上推广方案资阳地seo
  • 荥阳高端网站建设谷歌官方网站注册
  • 官方网站撰写策划书厦门seo代运营
  • 网站提升权重武汉网络推广平台
  • 做网站的一般多少钱百度推广话术全流程
  • 北海哪里做网站建设知乎营销推广
  • 简述网站开发的三层架构外贸建站与推广如何做
  • 制作一个有用户网站张家界seo