多线程--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() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的.各 ...
随机推荐
- Codeforces - 1195E - OpenStreetMap - 单调队列
https://codeforc.es/contest/1195/problem/E 一个能运行但是会T的版本,因为本质上还是\(O(nmab)\)的算法.每次\(O(ab)\)初始化矩阵中的可能有用 ...
- pthread_cond_timedwait
该函数用于在同时等待条件变量时提供超时功能,不过该函数的超时时间是一个绝对时间.默认使用系统时间,这意味这,若修改系统时间,那么超时就不准确,有可能提前返回,也可能要几年才返回.这在某些需求下会导致b ...
- JavaScript常用字符串方法和属性
一直以来 在喜马拉雅上听 陪你读书(JavaScript WEB前端) 主播沙翼 讲的很好 果断买了这本书 现在做个笔记 var str = ‘abcd’ str.charAt(0); // ...
- 使用纯php构建一个简单的PHP服务器
使用原生PHP构建一个简单的PHPWeb服务器 1.目录机构 webserver --src -- Response.php -- Server.php -- Request.php -- vendo ...
- Codecraft-17 and Codeforces Round #391 - C
题目链接:http://codeforces.com/contest/757/problem/C 题意:给定n个gym和m个Pokemon的类型,然后给你每个gym内的Pokemon未进化之前的类型, ...
- 广义Fibonacci数列找循环节 学习笔记
遇到了2019ICPC南昌赛区的网络赛的一道题,fn=3*fn-1+2*fn-2,有多次询问求fn.总结起来其实就是在模P意义下,O(1)回答广义斐波那契额数列的第n项,可以说是一道模板题了. 这道题 ...
- 苹果正制造一款疯狂的“16K”VR耳机,效果到底有多牛?
苹果一直以来都有传闻称正在研发一副增强现实眼镜,但今天的一份报告显示,他们希望在虚拟现实领域与Google,微软和Facebook竞争. 据CNET报道,苹果公司着眼于2020年发布的将AR和VR技术 ...
- 编写mapreduce的程序的套路
https://blog.csdn.net/qq_42881421/article/details/83543926 给出下面6个经典案例: http://www.cnblogs.com/xia520 ...
- C#高级编程42章 MVC
42.1 ASP.NET MVC 路由机制 网络介绍链接 按照传统,在很多Web框架中(如经典的ASP.JSP.PHP.ASP.NET等之类的框架),URL代表的是磁盘上的物理文件.例如,当看到请求h ...
- 【HDOJ6608】Fansblog(威尔逊定理)
题意:给定质数p,求q!模p的值,其中q为小于p的最大质数 1e9<=p<=1e14 思路:根据质数密度近似分布可以暴力找q并检查 找到q后根据威尔逊定理: 把q+1到p-1这一段的逆元移 ...