多线程--ThreadLocal类
一.ThreadLocal类简介
--此类是在整个开发过程中至关重要的类,他主要是在开发过程中解决了核心资源和多线程并发访问的处理情况
--在真正去了解ThreadLocal类作用的时候,我们可以先编写一个简单的程序做一个前期的分析
--范例:现在定义这样的一个结构
package 多线程.threadlocal类; /**
* @author : S K Y
* @version :0.0.1
*/
class Channel { //消息的发送通道
private static Message message; public static void setMessage(Message message) {
Channel.message = message;
} public static void send() { //发送消息
System.out.println("消息发送: " + message.getInfo());
}
} class Message { //要发送的消息体
private String info; public String getInfo() {
return info;
} public void setInfo(String info) {
this.info = info;
}
} public class MyThreadLocal {
public static void main(String[] args) {
Message message = new Message(); //实例化消息主体对象
message.setInfo("test"); //设置要发送的消息内容
Channel.setMessage(message);
Channel.send(); //发送消息
}
}
--当前的程序实现是单线程的,如果在多线程的状态下它能否实现完全一致的操作效果呢,启动三个线程进行测试
class Channel { //消息的发送通道
private static Message message; public static void setMessage(Message message) {
Channel.message = message;
} public static void send() { //发送消息
System.out.println(Thread.currentThread().getName() + " 消息发送: " + message.getInfo());
}
}
public class MyThreadLocal {
public static void main(String[] args) {
new Thread(() -> {
Message message = new Message(); //实例化消息主体对象
message.setInfo("第一个线程的消息信息"); //设置要发送的消息内容
Channel.setMessage(message);
Channel.send(); //发送消息
},"消息发送者A").start();
new Thread(() -> {
Message message = new Message(); //实例化消息主体对象
message.setInfo("第二个线程的消息信息"); //设置要发送的消息内容
Channel.setMessage(message);
Channel.send(); //发送消息
},"消息发送者B").start();
new Thread(() -> {
Message message = new Message(); //实例化消息主体对象
message.setInfo("第三个线程的消息信息"); //设置要发送的消息内容
Channel.setMessage(message);
Channel.send(); //发送消息
},"消息发送者C").start();
}
}
--理论上消息的发送应该是各自发送各自的消息内容,但是我们观察程序运行结果
消息发送者A 消息发送: 第二个线程的消息信息
消息发送者C 消息发送: 第三个线程的消息信息
消息发送者B 消息发送: 第二个线程的消息信息 Process finished with exit code 0
--这个时候消息的处理产生了影响,在Channel类的实现中,是依赖使用static Message message来完成的,在线程A设置完对象信息但还未发送时,线程B就进行了对象了覆盖,这样就将会造成消息内容的覆盖问题,这个过程就被称之为不同步,面对这样的情况,解决同步问题在Channel核心结构不改变的情况下需要考虑每个线程的运行情况,对于Channel类而言除了要保留有发送的消息之外,还应该多存放有一个每一个线程的标记(当前线程的使用标记),那么这个时候就可以通过ThreadLocal类来存放数据
--在ThreadLocal类中定义有如下方法
构造方法:public ThreadLocal()
T get()
返回当前线程的此线程局部变量的副本中的值。
protected T initialValue()
返回此线程局部变量的当前线程的“初始值”。
void remove()
删除此线程局部变量的当前线程的值。
void set(T value)
将当前线程的此线程局部变量的副本设置为指定的值。
static <S> ThreadLocal<S> withInitial(Supplier<? extends S> supplier)
创建线程局部变量。
--范例:使用ThreadLocal来存放数据变量实现数据的同步
package 多线程.threadlocal类; /**
* @author : S K Y
* @version :0.0.1
*/
class Channel { //消息的发送通道
//私有静态常量
private static final ThreadLocal<Message> THREAD_LOCAL = new ThreadLocal<>(); public static void setMessage(Message message) {
THREAD_LOCAL.set(message);
} public static void send() { //发送消息
System.out.println(Thread.currentThread().getName() + " 消息发送: " + THREAD_LOCAL.get().getInfo());
}
} class Message { //要发送的消息体
private String info; public String getInfo() {
return info;
} public void setInfo(String info) {
this.info = info;
}
} public class MyThreadLocal {
public static void main(String[] args) {
new Thread(() -> {
Message message = new Message(); //实例化消息主体对象
message.setInfo("第一个线程的消息信息"); //设置要发送的消息内容
Channel.setMessage(message);
Channel.send(); //发送消息
},"消息发送者A").start();
new Thread(() -> {
Message message = new Message(); //实例化消息主体对象
message.setInfo("第二个线程的消息信息"); //设置要发送的消息内容
Channel.setMessage(message);
Channel.send(); //发送消息
},"消息发送者B").start();
new Thread(() -> {
Message message = new Message(); //实例化消息主体对象
message.setInfo("第三个线程的消息信息"); //设置要发送的消息内容
Channel.setMessage(message);
Channel.send(); //发送消息
},"消息发送者C").start();
}
}
--运行结果
消息发送者A 消息发送: 第一个线程的消息信息
消息发送者C 消息发送: 第三个线程的消息信息
消息发送者B 消息发送: 第二个线程的消息信息 Process finished with exit code 0
多线程--ThreadLocal类的更多相关文章
- Java多线程——ThreadLocal类的原理和使用
Java多线程——ThreadLocal类的原理和使用 摘要:本文主要学习了ThreadLocal类的原理和使用. 概述 是什么 ThreadLocal可以用来维护一个变量,提供了一个ThreadLo ...
- Java多线程——ThreadLocal类
一.概述 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量).也许把它命名 ...
- java核心-多线程(9)- ThreadLocal类
1.背景 ThreadLocal类我想一般的码农或初级程序员在平时开发中基本上接触不到,但是面试老师会问.往高级点走会遇到这个类.这个类不是为了解决资源的竞争问题,而是为每个线程提供同一个容器 ...
- ThreadLocal类详解:原理、源码、用法
以下是本文目录: 1.从数据库连接探究 ThreadLocal 2.剖析 ThreadLocal 源码 3. ThreadLocal 应用场景 4. 通过面试题理解 ThreadLocal 1.从数据 ...
- 2015年11月26日 Java基础系列(三)ThreadLocal类初级学习
序,ThreadLocal类是为了解决多线程的安全问题.线程安全的意思也就是说每个线程操作自己的变量,不要对其他线程的值造成影响. 在很多情况下,ThreadLocal比直接使用synchronize ...
- ThreadLocal类的实现用法
ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量).也许把它命名为Thread ...
- 深入研究java.lang.ThreadLocal类(转)
引用:http://lavasoft.blog.51cto.com/62575/51926/ 一.概述 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并 ...
- 深入研究java.lang.ThreadLocal类
一.概述 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量).也许 ...
- ThreadLocal类的理解
首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的.各 ...
随机推荐
- 使用MyEclipse创建Servlet
https://www.yiibai.com/servlet/creating-servlet-in-myeclipse-ide.html 如何在myeclipse IDE中创建Servlet? 要在 ...
- 06.Linux-RedHat系统网卡服务连不上活跃连接路径变化
问题:在新装的系统中,重启网卡的时候出现如下报错 [root@localhost ~]# service network restart 正在关闭接口 eth0: 设备状态:3 (断开连接) [确定] ...
- 203-基于ARM和双TI DSP TMS320C6678的6UCPCI高清编解码处理平台
基于ARM和双TI DSP TMS320C6678的6UCPCI高清编解码处理平台 1.产品简介 该板卡由我公司自主研发,以TI Cortex-A8.TI 双DSP TMS320C6678为设计核心, ...
- 解释ARP协议和RARP协议
解释ARP(地址解析协议) 首先,每个主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址之间的对应关系. 当源主机要发送数据时,首先检查ARP列表中是否有对应IP地址的目的主 ...
- 前端学习(三十四)对象&模块化(笔记)
人,工人 //类的定义 function Person(name,age){ //构造函数 //工厂模式 //1.原料 //var obj = new ...
- Mongodb使用shell实现与javascript的动态交互
关于利用mongodb的shell执行脚本,这点在以前的文章中有点遗漏:现在在此篇博客中做个补充: 一.在命令行中传入脚本文件 定义一个javasciprt文件,名称为:script1.js,内容如下 ...
- 固定内网ip的方法
ip最后一位找一个不常用的,比如200之后的,ping不通它就用它. 子网掩码,默认网关保持和原来的一样. DNS要填公司的,网上查的不能用,因为他们是互联网上的.主备:XXXXXX/XX (之前填的 ...
- v-for中的key的使用【key的作用主要是是为了高效的更新虚拟DOM】
vue中列表循环需加:key="唯一标识" 唯一标识可以是item里面id index等,因为vue组件高度复用增加Key可以标识组件的唯一性,为了更好地区别各个组件 key的作用 ...
- Jmeter性能测试,使用ServerAgent监控服务端性能指标
一.jmeter1.下载JMeter Plugins Manager.jar放到你的jmeter\lib\ext目录下2.启动jmeter,进入Plugins Manager找到perfmon安装这个 ...
- AGC002 F Leftmost Ball——DP
题目:https://atcoder.jp/contests/agc002/tasks/agc002_f 充要条件是前缀0的个数 >= 颜色种数. 设计 DP ,放一个颜色的时候就把所有该颜色的 ...