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

网站建设外链广告平面设计软件有哪些

网站建设外链,广告平面设计软件有哪些,湖南网站营销seo多少费用,网络优化工程师需要学什么深入理解 InheritableThreadLocal:在多线程中传递上下文 在 Java 多线程编程中,ThreadLocal 作为一个重要的工具,允许每个线程维护独立的变量副本。然而,默认的 ThreadLocal不会被子线程继承,这在一些场景下会带来问题…

深入理解 InheritableThreadLocal:在多线程中传递上下文

在 Java 多线程编程中,ThreadLocal 作为一个重要的工具,允许每个线程维护独立的变量副本。然而,默认的 ThreadLocal不会被子线程继承,这在一些场景下会带来问题。

为了解决这个问题,Java 提供了 InheritableThreadLocal,它允许 子线程自动继承父线程的变量。本文将深入探讨 InheritableThreadLocal 的使用场景、实现原理及注意事项。


1. 为什么需要 InheritableThreadLocal?

在实际开发中,我们可能会遇到 父线程中设置了一些上下文数据,希望子线程也能使用 的情况,例如:

  • 日志跟踪(每个请求的唯一 ID 需要在多个线程之间共享)
  • 用户上下文(用户身份信息需要在子线程中保持一致)
  • 事务管理(跨线程传递事务信息)

示例:普通 ThreadLocal 不会被子线程继承

public class ThreadLocalExample {private static final ThreadLocal<String> threadLocal = new ThreadLocal<>();public static void main(String[] args) {threadLocal.set("父线程的数据");Thread childThread = new Thread(() -> {System.out.println("子线程读取的值: " + threadLocal.get()); // 预期:父线程的数据,实际:null});childThread.start();}
}

输出:

子线程读取的值: null

可以看到,ThreadLocal 变量并 不会被子线程继承,这导致子线程无法获取父线程的数据。


2. InheritableThreadLocal 让子线程继承变量

InheritableThreadLocalThreadLocal 的子类,它会自动将父线程的值拷贝到子线程,从而让子线程可以访问到父线程的数据。

示例:使用InheritableThreadLocal

public class InheritableThreadLocalExample {private static final InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>();public static void main(String[] args) {inheritableThreadLocal.set("父线程的数据");Thread childThread = new Thread(() -> {System.out.println("子线程读取的值: " + inheritableThreadLocal.get());});childThread.start();}
}

输出:

子线程读取的值: 父线程的数据

可以看到,子线程 成功继承了 父线程的 InheritableThreadLocal 变量的值。


3. InheritableThreadLocal 的工作原理

ThreadLocal 变量存储的本质是 Thread 对象中的 ThreadLocalMap,每个线程都有自己的 ThreadLocalMap,它存储了 ThreadLocal 变量及其对应的值。

普通 ThreadLocal 的存储方式

普通的 ThreadLocal 只在当前线程的 ThreadLocalMap 里存储数据:

Thread -> ThreadLocalMap -> (ThreadLocal, value)

当子线程启动时,它的 ThreadLocalMap是空的,所以获取 ThreadLocal 值时会返回 null

InheritableThreadLocal** 的存储方式**

InheritableThreadLocal 在 **创建子线程时,会自动拷贝父线程的 ThreadLocalMap,因此子线程可以访问父线程的数据:

父线程 -> ThreadLocalMap -> (InheritableThreadLocal, value)
↓
复制到子线程的 ThreadLocalMap

Thread.start() 被调用时,Java 会执行 Thread.init() 方法,它会检查是否存在 InheritableThreadLocal 并进行复制。


4. InheritableThreadLocal 的应用场景

(1) 日志追踪

在分布式系统或微服务架构中,我们通常需要在不同线程中追踪同一个请求的日志。例如,每个请求都会有一个 traceId,在所有的日志中都能找到它:

public class LogTraceExample {private static final InheritableThreadLocal<String> traceIdThreadLocal = new InheritableThreadLocal<>();public static void main(String[] args) {traceIdThreadLocal.set("TRACE-ID-12345");Thread childThread = new Thread(() -> {System.out.println("子线程日志 traceId: " + traceIdThreadLocal.get());});childThread.start();}
}

这样,我们可以在所有的子线程中 保持相同的traceId,确保日志能够正确追踪。


(2) Spring 中的用户上下文

Spring Boot 中,我们经常需要在多线程环境下共享用户信息,比如 UserContext

public class UserContext {private static final InheritableThreadLocal<String> userThreadLocal = new InheritableThreadLocal<>();public static void setUser(String user) {userThreadLocal.set(user);}public static String getUser() {return userThreadLocal.get();}public static void clear() {userThreadLocal.remove();}
}

然后在 Controller 里使用:

@RestController
@RequestMapping("/user")
public class UserController {@GetMapping("/info")public String getUserInfo(@RequestParam String username) {UserContext.setUser(username);new Thread(() -> {System.out.println("子线程访问用户: " + UserContext.getUser());}).start();return "主线程访问用户: " + UserContext.getUser();}
}

这样,子线程也能访问用户信息,实现跨线程的数据共享。


5. InheritableThreadLocal 的注意事项

  1. 子线程继承的是拷贝值,而不是引用
    • 这意味着如果 父线程之后修改了值,子线程不会感知到
  2. 内存泄漏风险
    • 一定要在 线程执行完后调用 remove() 清理数据,否则可能导致内存泄漏:
public static void clear() {userThreadLocal.remove();
}
  1. 线程池中的问题
    • InheritableThreadLocal不会自动清理线程池中的数据,因为线程池中的线程会被复用。可以使用 TransmittableThreadLocal 解决。

6. TransmittableThreadLocal 解决线程池问题

当使用 InheritableThreadLocal 时,在 线程池 中创建的线程不会自动继承新的值,因为线程池会复用线程。
Alibaba 开源的 TransmittableThreadLocal 可以解决这个问题:

TransmittableThreadLocal<String> threadLocal = new TransmittableThreadLocal<>();

它可以 在父线程修改值后,确保线程池的子线程也能正确获取最新的值


7. 总结

方案是否继承到子线程适用场景
ThreadLocal❌ 不继承每个线程独立变量
InheritableThreadLocal✅ 继承但不会动态更新继承父线程变量,如日志追踪、用户上下文
TransmittableThreadLocal✅ 适用于线程池线程池中的上下文传递

最佳实践
优先使用ThreadLocal,仅在确实需要跨线程传递变量时才使用 InheritableThreadLocal
如果使用线程池,考虑TransmittableThreadLocal

InheritableThreadLocal 是一个 简单而强大的工具,但要注意 内存泄漏和线程池问题,合理使用才能发挥最大作用! 🚀


文章转载自:

http://GmXzjdBx.zpstm.cn
http://EENYul1U.zpstm.cn
http://m2JT8MLY.zpstm.cn
http://Sm9dJhZf.zpstm.cn
http://ORZTKHz1.zpstm.cn
http://6LwwUtsF.zpstm.cn
http://wq9xwQzL.zpstm.cn
http://yFFGKkHf.zpstm.cn
http://sJyvnb9q.zpstm.cn
http://lbGPC98M.zpstm.cn
http://mzlGAReW.zpstm.cn
http://dM4GyPrs.zpstm.cn
http://6IjSwtnU.zpstm.cn
http://HD8OZgDW.zpstm.cn
http://JsncWDYu.zpstm.cn
http://AiBJjCna.zpstm.cn
http://kmeguJQE.zpstm.cn
http://ZIYhT98G.zpstm.cn
http://Vhecj7C1.zpstm.cn
http://4Fep0qSk.zpstm.cn
http://SVd0dyfb.zpstm.cn
http://KRPxAPdp.zpstm.cn
http://wUBBUMmG.zpstm.cn
http://nJWe1XJC.zpstm.cn
http://aFjKms77.zpstm.cn
http://xziWJmTZ.zpstm.cn
http://HA3UW6X4.zpstm.cn
http://jTwJuiay.zpstm.cn
http://B61pR451.zpstm.cn
http://lc6RQ7hj.zpstm.cn
http://www.dtcms.com/wzjs/637364.html

相关文章:

  • 天津网站制作的公司展厅策划设计公司
  • 山东营销网站建设联系方式360建筑网密码忘了
  • 海阳网站制作通过ip直连打开网站要怎么做
  • 海外英文建站优秀交互设计网站
  • 怎么使用网站上的模板微信小程序认证费用
  • 东莞网络营销型网站国外友链买卖平台
  • 如何查看网站空间网站设计相似侵权吗
  • 网站制作建设哪家公司好哪里有免费建站平台
  • 北京企业网站优化郑州网站制作公司
  • 旅行网站开发wordpress模板 物流
  • 网站内部链接的策略wordpress用户可以互加好友
  • html怎么做网站首页wordpress 升级方法
  • 前端作业做一个网站为什么php做不了大网站
  • 苏州建设培训中心南阳seo网站排名优化
  • 深圳制作网站建设推广网页设计总结与体会200字
  • 建微信网站模板网络营销工具和方法
  • 网站模板放哪网站建设价格差异多少
  • 网站营销怎么做外贸软件app
  • 哪些网站可以做养殖的广告做网站初级教程
  • 为网站设计手机版网站是做推广好还是优化好
  • 天津学网站建设资阳地seo
  • jsp做的个人网站网站建设中企动力强
  • 建站企业网站wordpress oa插件
  • 广东网广东网站建设阳朔县建设规划局网站
  • 网站建设的所需解决的技术问题衡水建设局网站首页
  • 杭州手机网站制作中国菲律宾混血
  • dw网页设计模板网站建站怎么赚钱
  • 深圳做企业网站的公司南浔建设局网站
  • 个人网站如何在工信部备案域名查询服务器ip
  • 城乡住房和城乡建设部网站站长工具网址是多少