线程安全问题的本质:对“共享资源”,“并发操作”导致的数据不一致问题。注意两个关键字:“共享资源”,“并发操作”

通常解决线程安全问题通过加锁,互斥访问共享资源

而ThreadLocal换了个思路解决问题,不访问“共享资源”,每个线程都访问自己的资源

简单用一下TheadLocal

public class ThreadLocalTest {public static void simpleUseThreadLocal(){ThreadLocal<Integer> threadLocalObj = new ThreadLocal();// 1threadLocalObj.set(1);// 2System.out.println(Thread.currentThread().getName()+":"+threadLocalObj.get());}public static void main(String[] args) throws InterruptedException {simpleUseThreadLocal();}
}
//输出, main:1

看看ThreadLocal相关源码

public class ThreadLocal<T> {public ThreadLocal() {}public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);}ThreadLocalMap getMap(Thread t) {return t.threadLocals;}void createMap(Thread t, T firstValue) {t.threadLocals = new ThreadLocalMap(this, firstValue);}static class ThreadLocalMap {}
}
public class Thread implements Runnable {ThreadLocal.ThreadLocalMap threadLocals = null;....
}

本程序的执行时,main线程的内存示意图

其实ThreadLocal的原理很简单,执行ThreadLocal的set方法时,可以获取当前的执行线程(Thread.currentThread()),线程下放入一个Map,Map中放入你的value,key为ThreadLocal对象。

get方法同理:获取执行线程,从执行线程的Map中get出key为“ThreadLocal对象”的value

1、ThreadLocal#set()方法源码分析

2、ThreadLocal#get()方法源码分析

3、RocketMQ应用案例

在RocketMQ中,应用程序使用RocketMQ的客户端向Broker发送消息时,为了保证Broker中的每个MessageQueue的负载均衡,客户端应该均衡的从选择MessageQueue进行发送

多线程并发使用一个生产者(DefaultMQProducer)不断地发送消息时,如何均衡的从多个MessageQueue中选择一个进行发送呢?


RocketMQ就是使用的ThreadLocal,每个线程维护一个index,获取一个MessageQueue信息后index=index+1,这样每个线程就可以依次选择MessageQueue进行发送消息了。

如果不使用ThreadLocal,如何依次选择MessageQueue呢?可能就需要生产者维护一个index,然后多个线程同步互斥访问这个index了

4、总结

通过案例我们知道,在多线程并发编程时,为了保证线程安全,我们除了可以同步访问共享资源,还有另外一个选项:是不是可以访问共享资源呢?

特定的场景下选择ThreadLocal,没有互斥访问,在一定程度上可以提升程序的性能

图解ThreadLocal核心原理相关推荐

  1. 庖丁解牛 | 图解 RocketMQ 核心原理

    如何把开源项目用好,很大程度上是由学习路径决定的: a. fork下来,起一个demo,上一个测试环境,遇到问题再去社区提问或找些实践文章:b. 把官方文档通读一遍,理解下产品.特点和应用场景:c. ...

  2. CyclicBarrier 使用核心原理 图解

    疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 面试必备 + 面试必备 [博客园总入口 ] 疯狂创客圈 经典图书 : <Sprin ...

  3. 深入理解RCU|核心原理

    hi,大家好,今天给大家分享并行程序设计中最重要的锁-RCU锁,RCU锁本质是用空间换时间,是对读写锁的一种优化加强,但不仅仅是这样简单,RCU体现出来的垃圾回收思想,也是值得我们学习和借鉴,各个语言 ...

  4. promise用法_图解 Promise 实现原理(四):Promise 静态方法实现

    作者:Morrain 转发链接:https://mp.weixin.qq.com/s/Lp_5BXdpm7G29Z7zT_S-bQ 前言 Promise 是异步编程的一种解决方案,它由社区最早提出和实 ...

  5. 图文详解 epoll 原理【Redis,Netty,Nginx实现高性能IO的核心原理】epoll 详解

    [Redis,Netty,Nginx 等实现高性能IO的核心原理] I/O 输入输出(input/output)的对象可以是文件(file), 网络(socket),进程之间的管道(pipe).在li ...

  6. JDK ThreadPoolExecutor核心原理与实践

    作者:vivo互联网服务器团队-Xu Weiteng 一.内容概括 本文内容主要围绕JDK中的ThreadPoolExecutor展开,首先描述了ThreadPoolExecutor的构造流程以及内部 ...

  7. 还不懂spring IOC核心原理?200行代码带你手撸一个

    Spring做为Java企业级应用的开源开发框架,早已成为Java后端开发事实上的行业标准,无数的公司选择Spring作为基础的开发框架. 使用Spring框架的人一定都听过Spring的IoC(控制 ...

  8. Redis 深度历险:核心原理与应用实践

    Redis 是互联网技术架构在存储系统中使用最为广泛的中间件,它也是中高级后端工程师技术面试中面试官最喜欢问的工程技能之一,特别是那些优秀的.竞争激烈的大型互联网公司(比如 Twitter.新浪微博. ...

  9. java.lang.ThreadLocal实现原理和源码分析

    java.lang.ThreadLocal实现原理和源码分析 1.ThreadLocal的原理:为每一个线程维护变量的副本.某个线程修改的只是自己的副本. 2.ThreadLocal是如何做到把变量变 ...

最新文章

  1. 二十二、新人成才之路《做人七项原则 做一个节俭惜福的人》
  2. Spring Boot 2.1.0 已发布,7 个重大更新!
  3. ObjC: Foundation Kit
  4. webpack入门(四)——webpack loader 和plugin
  5. 程序员如何日常解决错误问题
  6. centos 升级php5.5_CentOS 5.x 系统yum 升级php到5.2.x的方法(测试可用)
  7. python共享单车数据分析_共享单车数据可视化分析(Python/Seaborn)
  8. 常用USB芯片介绍(转串口、SPI 、单片机读写U盘)
  9. 海量实时广告流平台(DSP广告系统)架构设计与实践
  10. Android小程序-简易计算器的实现
  11. 启发式算法的基础定义与了解
  12. 该怎么学Python?自学Python的方法整理!
  13. 酒店管理系统(C语言)
  14. 利用FastReport传递图片参数,在报表上展示签名信息
  15. AUTOMATE THE BORING STUFF WITH PYTHON读书笔记 - 第2章:FLOW CONTROL
  16. clamav(clamav杀毒 启动)
  17. C# 矩阵和向量的相关计算(一)
  18. http://www.jianshu.com/p/55458caf0814
  19. CAA开发之工程图---工程图开发自定义核心函数 1
  20. 解决ubuntu打不开软件更新器和软件中心的问题

热门文章

  1. [Ext JS 4] 实战之Grid, Tree Gird 添加按钮列
  2. 华为服务器装系统一直在读盘,系统重装一直在启动服务器
  3. mysql注解批量添加mybatis_Mybatis注解方式 实现批量插入数据库
  4. pymysql.err.OperationalError: (2006, “MySQL server has gone away (BrokenPipe
  5. 装完机,启grub+Linux,linux一路填坑...
  6. java.sql.SQLException: null, message from server: “Host ‘xxx.xxx.xxx.xxx‘ is not allowed to
  7. oracle复制表结构与表数据
  8. mysql如何将多条返回结果的一个字段合并成一条
  9. list的交集,差集,并集
  10. Win10关闭windows defender杀毒软件的方法