ThreadLocal叫线程本地变量,他为每个线程都创建了一个副本变量,每个线程都只能访问自己的副本变量。
我们直接用一个例子来解释ThreadLocal。

class Message{private String note;public void setNote(String note) {this.note = note;}public String getNote() {return note;}
}
class MessageConsumer{public void print(){System.out.println(Thread.currentThread().getName() + "..." + Test20.msg.getNote());}
}public class Test20 {public static Message msg;public static void main(String[] args) {new Thread(() -> {Message msg = new Message();msg.setNote("你好啊");Test20.msg = msg;new MessageConsumer().print();}, "用户A").start();new Thread(() -> {Message msg = new Message();msg.setNote("Hello");Test20.msg = msg;new MessageConsumer().print();}, "用户B").start();}}

首先我们有一个Message类,提供信息的读写,还有一个信息的打印类MessageConsumer,然后再客户端创建两个线程,这里有一个Message类型的成员,用它来作为全局数据区,减少引用的传递。接下来我们来看看这样做的后果是什么:

执行三次,得到三个结果,而且两个线程打印出来的结果竟都是一样的,这就是变量没有同步的问题,我们来分析一下这个原因:两个或多个线程分别设置了Message信息,这里有一个全局数据区msg,这是线程共享的,用户A线程设置了信息,还没等它打印出来,用户B线程又设置了这个msg,导致后面的线程把前面的线程覆盖了,所以才会出现结果都相同的情况。这时就需要用ThreadLocal来设置一个线程本地变量,每个线程只能操作它自己的副本变量。代码如下:

class Message{private String note;public void setNote(String note) {this.note = note;}public String getNote() {return note;}
}
class MessageConsumer{public void print(){System.out.println(Thread.currentThread().getName() + "..." + MyUtil.get().getNote());}
}
class MyUtil{public static ThreadLocal<Message> threadlocal = new ThreadLocal<>();public static void set(Message msg){threadlocal.set(msg);}public static Message get(){return threadlocal.get();}
}
public class Test20 {public static void main(String[] args) {new Thread(() -> {Message msg = new Message();msg.setNote("你好啊");MyUtil.set(msg);new MessageConsumer().print();}, "用户A").start();new Thread(() -> {Message msg = new Message();msg.setNote("Hello");MyUtil.set(msg);new MessageConsumer().print();}, "用户B").start();}}

再来看一下结果:

这样就实现了变量同步,每个线程只改变自己的数据。

用一个例子来解释ThreadLocal相关推荐

  1. [机器学习]一个例子完美解释朴素贝叶斯分类器

    何为"朴素":属性条件独立性假设 如果已知条件不止一个属性,二是多个呢,这个时候贝叶斯公式可以写作 上述公式假设特征属性 a1,a2⋯ 相互独立,这也是"朴素" ...

  2. 什么是量子计算机?用一个简单例子来解释

    译者:王亮  作者:YK Sugi  原文:http://t.cn/EZAElk0 Hi,大家好! 不久前,我参观了加拿大温哥华的D-Wave Systems公司,这是一家制造前沿量子计算机的公司. ...

  3. java seda_Java seda,vm和direct之间有什么区别用camel解释它用一个例子

    我曾与seda合作并直接和我一起阅读文档.仍然无法想象seda的使用和直接. vm对我来说是新的.请用一个例子解释一下. 至少有四种不同的机制,一种Camel路由可以直接将数据传递给另一种. &quo ...

  4. Java 堆内存泄漏分析的一个例子

    Java 程序开发者,多多少少都遇到过 Java 堆内存溢出的错误,错误发生时可以在日志文件中看到 java.lang.OutOfMemoryError: Java heap space 字样.不像  ...

  5. python中self_一个例子带你入门Python装饰器

    ============ 欢迎关注我的公众号:早起python ============ 前言 在还未正式发布的python3.9中,有一个新功能值得关注,那就是任意表达式可以作为装饰器,如果你还不知 ...

  6. Flutter 初学者的简单例子充分解释

    Flutter 初学者的简单例子充分解释 大家好,我是坚果,我的公众号"坚果前端", 关于 Flutter 语言: Flutter 是一种语言工具,允许您使用单一的原生编程语言代码 ...

  7. 一个例子带你搞懂python作用域中的global、nonlocal和local

    在编程中,只要接触过函数的,我相信都理解什么是全局变量和局部变量,概念比较简单,这里就不做解释了.在python中,用global语句就能将变量定义为全局变量,但是最近又发现有个nonlocal,一时 ...

  8. SDN精华问答 | 使用SDN的一个例子

    SDN火热了好一阵子,无论运营商.政府企业.投资机构,一段时间,不知道SDN.不能甩几个SDN相关的名词术语,似乎都落后于时代了.今天,就来看看关于SDN的精华问答吧. 1 Q:为什么会出现SDN呢? ...

  9. Webpack入门——使用Webpack打包Angular项目的一个例子

    (一)什么是Webpack Webpack是一个前端的模块管理工具(module bundler),以下是webpack的官网:http://webpack.github.io/,一进入官网可以看到下 ...

最新文章

  1. Android:手把手教你 实现Activity 与 Fragment 相互通信(含Demo)
  2. 重新配对_郑思维和陈清晨当年配对也很强,为什么被拆开重新和黄雅琼配对
  3. while和for循环读取大文件三种读取文件方式
  4. python实现监控增量_Python 快速计算增量的方法
  5. Nginx静态资源压缩实战内容介绍
  6. js中怎么写自执行函数
  7. java内存泄漏和内存溢出_Java和内存泄漏
  8. 比较两大虚拟桌面厂商的系统镜像管理
  9. php集成环境还需要mysql吗_是选择php集成环境好还是分开安装的原生版好
  10. 分布式存储绝不简单 —— UCan下午茶-武汉站纪实
  11. Bailian3709 2进制转化为3进制【进制】
  12. 计算机并口优点,并口光驱优缺点有哪些 并口光驱如何转串口
  13. 嵌入式FTP服务器的移植与配置:VSF…
  14. html5 mediarecorder,用浏览器轻松录制音频、视频—— MediaRecorder API
  15. Proptech崛起,房地产产业数智化,成了2020年的新风口
  16. 【工艺】 CNC(数控机床)加工工艺
  17. 可视化丨用数据分析福尔摩斯探案集
  18. Dockerfile配置APM监控实现Java容器的性能监控
  19. R语言并行计算实战教程
  20. 华为智慧屏 鸿蒙UI 适配荣耀,鸿蒙OS首秀 荣耀智慧屏发布,仅3799元起

热门文章

  1. PLSQL查询中文乱码
  2. 光子神经网络的应用及发展概述
  3. 【高等代数】线性空间的定义
  4. Android.Settings类设置默认输入法
  5. 解决不同浏览器对css支持问题详解
  6. 兼莱宝分享:适合上班族空闲时间做的三种靠谱副业?
  7. 在线 阿里矢量 失效 配置后仍不发显示 icon
  8. vue3 项目添加水印的实现方法
  9. 计算机学院 运动会口号,信息与计算机系运动会口号
  10. 常见漏洞验证测试方法