目录

一、why:为什么要用ThreadLocal

1.1示例:不使用ThreadLocal,使用static,每个值修改同一个变量,产生错误

1.2运行结果,可能有几种可能性:

1.3使用ThreadLocal

1.4结果:都是2

二、ThreadLocal的使用

2.1ThreadLocal类接口很简单,常用的有4个方法

2.2remove的测试

2.3执行结果

三、ThreadLocal初始化方法的使用

1、实现方法initialValue

2、通过lomoba表达式

四、ThreadLocal在线程中的使用,即怎么让多个线程使用threadLocal

1、线程对象内部自定义threadLocal

2、通过构造函数传递进线程的ThreadLocal变量


一、why:为什么要用ThreadLocal

1.1示例:不使用ThreadLocal,使用static,每个值修改同一个变量,产生错误

/*** 不使用ThreadLocal共同使用变量,使用static,每个值修改同一个变量,产生错误* @author: honry.guan* @create: 2020-06-07 18:53**/
public class NoThreadLocalTest extends Thread{private static int num = 1;@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+": 开始执行,num = "+num);num  = num + 1;System.out.println(Thread.currentThread().getName()+" 结束,num = "+num);}public static void main(String[] args) {for (int i = 0; i < 3; i++) {NoThreadLocalTest t = new NoThreadLocalTest();t.start();}}
}

1.2运行结果,可能有几种可能性:

Thread-1: 开始执行,num = 1
Thread-0: 开始执行,num = 1
Thread-0 结束,num = 3
Thread-2: 开始执行,num = 1
Thread-1 结束,num = 2
Thread-2 结束,num = 4

也有可能是:

Thread-1: 开始执行,num = 1
Thread-2: 开始执行,num = 1
Thread-2 结束,num = 2
Thread-0: 开始执行,num = 1
Thread-0 结束,num = 4
Thread-1 结束,num = 4

1.3使用ThreadLocal

public class NoThreadLocalTest extends Thread{private ThreadLocal<Integer> num = new ThreadLocal<Integer>(){@Overrideprotected Integer initialValue() {return 1;}};@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+": 开始执行,num = "+num.get());num.set(num.get() + 1);System.out.println(Thread.currentThread().getName()+" 结束,num = "+num.get());}public static void main(String[] args) {for (int i = 0; i < 3; i++) {NoThreadLocalTest t = new NoThreadLocalTest();t.start();}}
}

1.4结果:都是2

Thread-0: 开始执行,num = 1
Thread-2: 开始执行,num = 1
Thread-2 结束,num = 2
Thread-1: 开始执行,num = 1
Thread-0 结束,num = 2
Thread-1 结束,num = 2

二、ThreadLocal的使用

2.1ThreadLocal类接口很简单,常用的有4个方法

• void set(Object value):设置当前线程的线程局部变量的值。

• public Object get():该方法返回当前线程所对应的线程局部变量。

• public void remove():移除变量,如果最开始是1,通过set修改之后,调用remove之后,get出来的值又变成1

• protected Object initialValue():初始,第一次调用set或get才执行,并且仅执行一次。

2.2remove的测试

public class NoThreadLocalTest extends Thread{private ThreadLocal<Integer> num = new ThreadLocal<Integer>(){@Overrideprotected Integer initialValue() {return 1;}};@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+": 开始执行,num = "+num.get());num.set(num.get() + 1);System.out.println(Thread.currentThread().getName()+" 结束,num = "+num.get());num.remove();System.out.println(Thread.currentThread().getName()+" 结束remove之后,num = "+num.get());}public static void main(String[] args) {for (int i = 0; i < 3; i++) {NoThreadLocalTest t = new NoThreadLocalTest();t.start();}}
}

2.3执行结果

Thread-1: 开始执行,num = 1
Thread-2: 开始执行,num = 1
Thread-0: 开始执行,num = 1
Thread-0 结束,num = 2
Thread-2 结束,num = 2
Thread-1 结束,num = 2
Thread-1 结束remove之后,num = 1
Thread-2 结束remove之后,num = 1
Thread-0 结束remove之后,num = 1

三、ThreadLocal初始化方法的使用

1、实现方法initialValue

private ThreadLocal<Integer> num = new ThreadLocal<Integer>(){@Overrideprotected Integer initialValue() {return 1;}
};

2、通过lomoba表达式

ThreadLocal<Integer> num = ThreadLocal.withInitial(()->1);

四、ThreadLocal在线程中的使用,即怎么让多个线程使用threadLocal

(我刚学的时候一直被这个事情困扰,自己手写几次之后明白)

只要在线程run方法中,调用ThreadLocal的get或者set,不管是线程对象内部自定义threadLocal,还是通过构造函数传递进线程的ThreadLocal变量。

1、线程对象内部自定义threadLocal

public class NoThreadLocalTest extends Thread{private ThreadLocal<Integer> num = new ThreadLocal<Integer>(){@Overrideprotected Integer initialValue() {return 1;}};@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+": 开始执行,num = "+num.get());num.set(num.get() + 1);System.out.println(Thread.currentThread().getName()+" 结束,num = "+num.get());num.remove();System.out.println(Thread.currentThread().getName()+" 结束remove之后,num = "+num.get());}public static void main(String[] args) {for (int i = 0; i < 3; i++) {NoThreadLocalTest t = new NoThreadLocalTest();t.start();}}
}

2、通过构造函数传递进线程的ThreadLocal变量

public class NoThreadLocalTest extends Thread{private ThreadLocal<Integer> num ;public NoThreadLocalTest(ThreadLocal<Integer> num) {this.num = num;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+": 开始执行,num = "+num.get());num.set(num.get() + 1);System.out.println(Thread.currentThread().getName()+" 结束,num = "+num.get());num.remove();System.out.println(Thread.currentThread().getName()+" 结束remove之后,num = "+num.get());}public static void main(String[] args) {ThreadLocal<Integer> num = ThreadLocal.withInitial(()->1);}
}

此时不论什么一个线程能够并发访问这个变量,对它进行写入、读取操作,都是线程安全的。

1.7 ThreadLocal的原理和使用详解相关推荐

  1. python的编程模式-Python设计模式之状态模式原理与用法详解

    本文实例讲述了Python设计模式之状态模式原理与用法.分享给大家供大家参考,具体如下: 状态模式(State Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类 ...

  2. DeepLearning tutorial(1)Softmax回归原理简介+代码详解

    FROM: http://blog.csdn.net/u012162613/article/details/43157801 DeepLearning tutorial(1)Softmax回归原理简介 ...

  3. DeepLearning tutorial(3)MLP多层感知机原理简介+代码详解

    FROM:http://blog.csdn.net/u012162613/article/details/43221829 @author:wepon @blog:http://blog.csdn.n ...

  4. DeepLearning tutorial(4)CNN卷积神经网络原理简介+代码详解

    FROM: http://blog.csdn.net/u012162613/article/details/43225445 DeepLearning tutorial(4)CNN卷积神经网络原理简介 ...

  5. Nginx(二):反向代理原理 与 配置文件详解

    相关阅读: Nginx(一):Nginx原理概述 与 安装步骤详解 Nginx(二):反向代理原理 与 配置文件详解 Nginx(三):负载均衡策略 与 Nginx静态服务器 Nginx(四):Ngi ...

  6. java linkedlist实例_Java Linkedlist原理及实例详解

    这篇文章主要介绍了Java Linkedlist原理及实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 定义:linkedlist属于链表结构 ...

  7. 【多元域除法】多项式除法电路原理及MATLAB详解

    关注公号[逆向通信猿]更精彩!!! 关于二元域上的两个元素的加法和乘法.多项式除法,在之前的博客 [有限域除法]二元多项式除法电路原理及MATLAB详解 子程序:sub_poly_div.m [有限域 ...

  8. 【多元域乘法】多项式乘法电路原理及MATLAB详解

    关注公号[逆向通信猿]更精彩!!! 关于二元域上的两个元素的乘法.多项式除法,在之前的博客 [有限域除法]二元多项式除法电路原理及MATLAB详解 子程序:sub_poly_div.m [有限域元素加 ...

  9. java设计模式观察者模式吗_Java设计模式之观察者模式原理与用法详解

    Java设计模式之观察者模式原理与用法详解 本文实例讲述了Java设计模式之观察者模式原理与用法.分享给大家供大家参考,具体如下: 什么是观察者模式 可以这么理解: 观察者模式定义了一种一对多的依赖关 ...

最新文章

  1. 鸿蒙程序如何上传,鸿蒙应用程序流转的实现
  2. 如何查看dede版本信息
  3. linux之uniq 命令详解
  4. python学了有什么用处-Python主要用途是哪些,跟机器学习等有啥关系呢?
  5. 虚拟机无法远程连接的问题
  6. Android Studio 添加 Genymotion插件
  7. 波士顿动力机器人全体出动,奉上新年之舞!
  8. content属性的4种用途
  9. 关于PHP代码的开始和结束标签书写,关于PHP结束标签?gt;的使用细节
  10. 计组之指令系统:3、CISC和RISC
  11. STM32那点事(2)_时钟树(下)
  12. IO流和集合的交集Properties类的介绍。
  13. ip变更 mysql无法启动_ubuntu mysql 更改IP导致mysql无法启动
  14. 小白记事本--链表--loading
  15. spring加载属性(properties)文件
  16. 2021美赛成绩查询证书下载
  17. c语言摄氏度单位ascii,请问温度标识 ℃,ASCII码怎么写
  18. 批处理打开/关闭休眠
  19. 电脑c盘分区太小如何可以扩大,电脑c盘不够用了,如何给电脑分区
  20. 银联支付前端页面跳转

热门文章

  1. 兰州大学信息与计算机科学硕,兰州大学信息科学与工程学院
  2. 关于LCD1602单独清除某一行的问题
  3. Fresco+Recycleview+OKhttp+Retrofit
  4. REST模式:POST,GET,PUT,DELETE,PATCH的含义与区别
  5. php 查询功能,php如何实现查询功能实现
  6. 笔记本电池不行 省电妙招
  7. plt画网格图_matplotlib子图与多种图形绘制
  8. 为什么建议大家使用 Linux 开发?有那么爽吗?
  9. c语言求对应学号的总成绩,c语言 求大神编程。定义一个学生结构体,包括学号、姓名、年龄、成绩。1、要求输入五个学生相应的信息,求学生成绩总和。2、输入一个学生学号,把该学生全部信息输出。...
  10. html只显示一句话_您所说的话:如何最大化多显示器设置