一.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类的更多相关文章

  1. Java多线程——ThreadLocal类的原理和使用

    Java多线程——ThreadLocal类的原理和使用 摘要:本文主要学习了ThreadLocal类的原理和使用. 概述 是什么 ThreadLocal可以用来维护一个变量,提供了一个ThreadLo ...

  2. Java多线程——ThreadLocal类

    一.概述   ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量).也许把它命名 ...

  3. java核心-多线程(9)- ThreadLocal类

    1.背景     ThreadLocal类我想一般的码农或初级程序员在平时开发中基本上接触不到,但是面试老师会问.往高级点走会遇到这个类.这个类不是为了解决资源的竞争问题,而是为每个线程提供同一个容器 ...

  4. ThreadLocal类详解:原理、源码、用法

    以下是本文目录: 1.从数据库连接探究 ThreadLocal 2.剖析 ThreadLocal 源码 3. ThreadLocal 应用场景 4. 通过面试题理解 ThreadLocal 1.从数据 ...

  5. 2015年11月26日 Java基础系列(三)ThreadLocal类初级学习

    序,ThreadLocal类是为了解决多线程的安全问题.线程安全的意思也就是说每个线程操作自己的变量,不要对其他线程的值造成影响. 在很多情况下,ThreadLocal比直接使用synchronize ...

  6. ThreadLocal类的实现用法

    ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量).也许把它命名为Thread ...

  7. 深入研究java.lang.ThreadLocal类(转)

    引用:http://lavasoft.blog.51cto.com/62575/51926/ 一.概述   ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并 ...

  8. 深入研究java.lang.ThreadLocal类

        一.概述   ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量).也许 ...

  9. ThreadLocal类的理解

    首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的.各 ...

随机推荐

  1. 任务21 :了解ASP.NET Core 依赖注入,看这篇就够了

    DI在.NET Core里面被提到了一个非常重要的位置, 这篇文章主要再给大家普及一下关于依赖注入的概念,身边有工作六七年的同事还个东西搞不清楚.另外再介绍一下.NET  Core的DI实现以及对实例 ...

  2. 如何卸载不用的VDP

    1.首先删除VDP 2.登录AD的DNS当中,删除VDP对应的DNS解析 3.1登陆 https://vcenterip/mob 这个地址. 输入你的管理员账号密码. 3.2进入content链接. ...

  3. Sybase 修改数据库默认排序

    我新建了一个sybase数据库,想用dump文件load,可是报数据库的排序不对,就去Centrol里面修改,但是还是报错,说是字符集不存在.办法如下: 打开命令行,进入到sybase的ASE-15_ ...

  4. Echarts 自定义数据视图

    toolbox : { show : true, feature : { dataView : { optionToContent : function(option) { // 行名称 var ax ...

  5. vsftpd配置详解

    匿名用户权限控制: anonymous_enable=YES #是否启用匿名用户 no_anon_password=YES #匿名用户login时不询问口令 anon_upload_enable=(y ...

  6. BZOJ3508 开灯 & [校内NOIP2018模拟20181027] 密码锁

    Time Limit: 10 Sec Memory Limit: 128 MB Description xx作为信息学界的大神,拥有众多的粉丝.为了感谢众粉丝的爱戴,xx决定举办一场晚会.为了气派,x ...

  7. Vue 滚动条动画

    <template> <div class="home-main"> <div class="progress-main"> ...

  8. 转载:Eclipse下的java工程目录

    原文链接:https://www.cnblogs.com/milantgh/p/4029003.html 对新手来讲,一个Java工程内部的多个文件夹经常会让大家困惑.更可恶的是莫名其妙的路径问题,在 ...

  9. 测试单点登录xml配置

    <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://w ...

  10. Word中页码及目录、参考文献的制做方法

    1.页码从正文开始 1.要想从哪里显示第一页,就在这页的前一页的最后一行最后的地方,插入分隔符---下一页2.然后在你想显示第一页的那一页双击页脚处,点击取消掉“链接到前一条页眉”.(这是为了取消原来 ...