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

教你做网站的视频如何seo搜索引擎优化

教你做网站的视频,如何seo搜索引擎优化,建站收入,做网站和推广1.TransmittableThreadLocal简介 com.alibaba.ttl.TransmittableThreadLocal(简称 TTL)是阿里巴巴开源的一个工具类,旨在解决 ThreadLocal 在线程池中无法传递上下文变量 的问题。它是对 InheritableThreadLocal 的增强,尤其适用…

1.TransmittableThreadLocal简介

com.alibaba.ttl.TransmittableThreadLocal(简称 TTL)是阿里巴巴开源的一个工具类,旨在解决 ThreadLocal 在线程池中无法传递上下文变量 的问题。它是对 InheritableThreadLocal 的增强,尤其适用于异步编程、线程池任务调度等场景。


1.1 核心功能

  1. 上下文传递:在普通线程池中,ThreadLocal 的值不会自动传递到新线程。TransmittableThreadLocal 通过 任务包装机制,将主线程的上下文变量传递到子线程(如线程池中的线程)中。

  2. 兼容性:它兼容 ThreadLocal 和 InheritableThreadLocal 的行为,同时支持 Java 8+ 的异步编程模型(如 CompletableFutureForkJoinPool 等)。

  3. 生命周期管理:支持在任务执行前后自动绑定/解绑上下文,避免内存泄漏。


1.2 典型使用场景

  • 分布式追踪(如 SkyWalking、Zipkin):在异步调用链中传递 Trace ID。
  • 日志上下文(如 MDC):在异步任务中保留请求标识(如用户 ID、请求 ID)。
  • 事务传播:在线程池中传递事务上下文(如 Seata 分布式事务)。
  • 权限验证:在异步任务中传递用户身份信息。

2.TransmittableThreadLocal基本用法

step1.引入依赖

<!-- Maven -->
<dependency><groupId>com.alibaba</groupId><artifactId>transmittable-thread-local</artifactId><version>2.12.1</version> <!-- 使用最新版本 -->
</dependency>

step2. 定义 TransmittableThreadLocal

import com.alibaba.ttl.TransmittableThreadLocal;public class Context {private static final TransmittableThreadLocal<String> CONTEXT = new TransmittableThreadLocal<>();public static void set(String value) {CONTEXT.set(value);}public static String get() {return CONTEXT.get();}
}

step3. 各种用法

import com.alibaba.ttl.TtlRunnable;ExecutorService executor = Executors.newFixedThreadPool(2);
// 主线程设置上下文
Context.set("Hello TTL");// 提交任务前包装 Runnable
// TtlRunnable 是 Runnable 的任务包装器
executor.submit(TtlRunnable.get(() -> {System.out.println("子线程: " + Context.get());
}, true)); // 第二个参数表示是否复制上下文//使用 TtlCallable 包装 Future 任务
// TtlCallable 是 Callable 的任务包装器
Future<String> future = executor.submit(TtlCallable.get(() -> {return "Result with context: " + Context.get();
}));//使用于 CompletableFuture
CompletableFuture.runAsync(TtlRunnable.get(() -> {System.out.println("CompletableFuture: " + Context.get());
}, true), executor);//如果使用自定义线程池,建议通过 TtlExecutors 包装:
Executor ttlExecutor = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(5));

关键特性

1. 自动传播:如果线程池本身是 TTL 兼容的(如使用 TtlExecutors 包装),则无需手动包装任务。

2. 线程池改造:如果使用自定义线程池,建议通过 TtlExecutors 包装:

ExecutorService ttlExecutor = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(2));

3. 清除机制:需要显式调用 remove() 避免内存泄漏:

try {Context.set("value");// 执行任务
} finally {Context.remove();
}

3. TransmittableThreadLocal实现上下文传递-完整demo

3.1 场景说明:

有一个“查询用户成绩”场景,需要将用户上下文(如用户ID、租户信息、AccessKey、Locale)在 Controller、Service 层甚至异步调用中传递。

3.2 实现目标

  • 用户请求进入系统后,从请求头中提取上下文信息。
  • 上下文信息在整个请求链路中自动传递,包括异步调用。
  • 上下文信息不会被多个请求交叉污染。
  • 上下文信息在请求结束后自动清理。

3.3 代码

step1. 定义用户上下文(UserContext)

import com.alibaba.ttl.TransmittableThreadLocal;
import lombok.Builder;
import lombok.Data;@Data
@Builder
public class UserContext {private static final TransmittableThreadLocal<UserContext> USER_CONTEXT= new TransmittableThreadLocal<UserContext>(){@Overrideprotected UserContext initialValue() {return new UserContext();}};/*** 用户ID*/private String userId;/*** 租户ID*/private String tenantId;/*** 访问密钥*/private String accessKey;/*** 语言*/private String locale;public UserContext() {}public UserContext(String userId, String tenantId, String accessKey, String locale) {this.userId = userId;this.tenantId = tenantId;this.accessKey = accessKey;this.locale = locale;}public static UserContext get() {return USER_CONTEXT.get();}public static void set(UserContext userContext) {USER_CONTEXT.set(userContext);}public static void remove() {USER_CONTEXT.remove();}}

step2. 配置拦截器(注入上下文UserContext)

定义一个UserContextInterceptor拦截器,用于从request Header中获取用户信息:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;public class UserContextInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {// 从请求头中提取用户信息(示例)String userId = request.getHeader("Custom-User-Id");String tenantId = request.getHeader("Custom-Tenant-Id");String accessKey = request.getHeader("Custom-Access-Key");String locale = request.getHeader("Custom-Accept-Language");// 设置用户信息UserContext userContext = UserContext.builder().userId(userId).tenantId(tenantId).accessKey(accessKey).locale(locale).build();UserContext.set(userContext);return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {// 务必在请求结束时清理上下文,避免内存泄漏UserContext.remove();}
}

注册UserContextInterceptor拦截器:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class UserContextWebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new UserContextInterceptor()).addPathPatterns("/**");}
}

step3.在 Service 层使用上下文(UserContext)

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import com.alibaba.ttl.threadpool.TtlExecutors;
import org.springframework.stereotype.Service;@Service
public class ScoreService {//配置异步线程池(使用 TtlExecutors),用于测试多线程场景下,子线程也能获取到主线程的上下文信息private Executor taskExecutor = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(5));public void queryScore() {String userId = UserContext.get().getUserId();String tenantId = UserContext.get().getTenantId();String accessKey = UserContext.get().getAccessKey();String locale = UserContext.get().getLocale();System.out.println("Sync start ====== ");System.out.println("current thead: " + Thread.currentThread().getName());System.out.println("Sync: Querying score for user: " + userId + ", tenant: " + tenantId +" accessKey: " + accessKey + ", locale: " + locale);}//多线程场景下,子线程也能获取到主线程的上下文信息public void queryScoreAsync() {taskExecutor.execute(() -> {String userId = UserContext.get().getUserId();String tenantId = UserContext.get().getTenantId();String accessKey = UserContext.get().getAccessKey();String locale = UserContext.get().getLocale();System.out.println("ASync start ====== ");System.out.println("current thead: " + Thread.currentThread().getName());System.out.println("Async: Querying score for user: " + userId + ", tenant: " + tenantId +" accessKey: " + accessKey + ", locale: " + locale);});}
}

step4. Controller层

@RestController
public class ScoreController {@Autowiredprivate ScoreService scoreService;@GetMapping("ScoreController/queryScore")public String queryScore() {scoreService.queryScore();scoreService.queryScoreAsync();return "ScoreController queryScore success!";}@GetMapping("ScoreController/hello")public String hello() {return "ScoreController say hello";}
}

step5.测试

启动应用后,在postman中做测试。

case1: 不设置Header,UserContext获取的值为null:

case2: 设置Header,UserContext获取的值为设置的值:

case3:使用 ThreadLocal 做对比测试,新建的子线程中无法获取到UserContext设置的值

将UserContext.USER_CONTEXT设置为 ThreadLocal:

@Data
@Builder
public class UserContext {//private static final TransmittableThreadLocal<UserContext> USER_CONTEXT//    = new TransmittableThreadLocal<UserContext>(){//    @Override//    protected UserContext initialValue() {//        return new UserContext();//    }//};// 改用 ThreadLocal,其他代码不变private static final ThreadLocal<UserContext> USER_CONTEXT = new ThreadLocal<UserContext>(){@Overrideprotected UserContext initialValue() {return new UserContext();}};
}

设置Header后,发送请求,新建的子线程中无法获取到UserContext设置的值:

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

相关文章:

  • 个人域名网站可以做企业站吗产品软文
  • 保定定兴网站建设百度搜索关键词指数
  • 沈阳专业建站极速一区二区三区精品
  • 静态网站建设背景网络推广和网络营销的区别
  • 优化网站内链宁波企业seo推广
  • 网站设计与开发网站策划网站建设 全网营销
  • 网站建设有哪几种seo推广外包报价表
  • 高清设计网站推荐站长统计工具
  • 网站群发推广软件今日油价92汽油价格表
  • 飓风 网站建设成都网站seo诊断
  • 番禺公司网站建设网络运营推广具体做什么工作
  • 网站如何制作学校的做淘宝关键词怎么选取
  • 英文企业网站模板网页版百度
  • 贵阳做网站电话全国知名网站排名
  • 长沙做网站建设公司哪家好企业建站公司
  • 网站建设买了服务器后怎么做app推广方案策划
  • 购物网站建站规划域名备案
  • 萧山品牌网站建设清理优化大师
  • 同城58找房子租房信息宁海关键词优化怎么优化
  • 做私服网站总是被攻击地推拉新接单平台
  • 芜湖营销网站建设学生网页设计模板
  • 网站备案帐户有什么用网站优化策略分析论文
  • wordpress英文仿站教程网站大全软件下载
  • wordpress videotube快速seo优化
  • 用服务器ip做网站域名网站维护费用
  • 网站推广应该坚持( )策略。关键词优化案例
  • 做网站的等级保护要多少钱百度竞价专员
  • 网站制作论文范文网站如何进行seo
  • 在线教育网站开发软件专业关键词排名软件
  • 管家婆免费资料网站2023必考十大时政热点