多线程--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() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的.各 ...
随机推荐
- dataTable获取所有数据
"drawCallback": function(settings,e) { var api = new $.fn.dataTable.Api( settings ); resul ...
- C# IEnumerable与IQueryable ,IEnumerable与IList ,LINQ理解Var和IEnumerable
原文:https://www.cnblogs.com/WinHEC/articles/understanding-var-and-ienumerable-with-linq.html 使用LINQ从数 ...
- 基于6U VPX的 SRIO 接口, 和PCIe 接口的msata 固态存储卡
基于6U VPX 的mSATA高性能数据存储板 一.板卡概述 该产品系我司自主研发.基于标准6U VPX架构. 二.产品特性 最大存储容量8TB 读写方式RAID0 ...
- Winfrom 弹出窗体位置设定
Winfrom 窗体弹出位置设定,其实就是两种模式,第一种模式是通过Winform提供的属性来设定:第二种模式是自定义,可以相对于软件本身,也可以是相对于屏幕. 一.第一种模式 使用Winform提供 ...
- $NOIP2018$ 暴踩全场计划实施方案
\(NOIP2018\) 暴踩全场计划实施方案 改完题辣!该更博辣!(这么激动干嘛反正又没人看) 我要取一个霸气的名字.于是就这样了.原本打算是暴踩yyb计划实施方案的(来啊互相伤害啊) 信心流选手就 ...
- 带有IBM大脑的浮动机器人被成功引导至太空
近日,带有IBM大脑的浮动机器人被成功引导至太空,在接下来的装运前往国际空间站包近三吨的研究和再补给材料. 机器人的全名是CrewInteractiveMobileCompanion:Cimon.它看 ...
- 爬虫技术:cookies池的维护
一:为什么要维护cookie 1.登录才能爬取内容 2.爬取频繁会被封号. 3.需要维护多个账号的cookie,实现大规模抓取 二:cookies的要求 1.自动登录更新 2.定期筛选验证 3.提供外 ...
- springmvc中拦截器配置格式
对于springmvc,有两种方式配置拦截器. 一是实现HandlerInterceptor接口,如 public class MyInterceptor1 implements HandlerInt ...
- 【leetcode】1020. Number of Enclaves
题目如下: Given a 2D array A, each cell is 0 (representing sea) or 1 (representing land) A move consists ...
- 每天一个Linux命令:find(20)
find find命令在目录结构中搜索文件,并执行指定的操作.Linux下find命令提供了相当多的查找条件,功能很强大.由于find具有强大的功能,所以它的选项也很多,其中大部分选项都值得我们花时间 ...