一.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. 阿里云ECS服务安装 nginx+php+MariaDB完整版

    安装 Nginx想在 CentOS 系统上安装 Nginx ,你得先去添加一个资源库,像这样: vim /etc/yum.repos.d/nginx.repo使用 vim 命令去打开 /etc/yum ...

  2. RabbitMQ ——消息属性Properties

    简介 发送消息可以为消息指定一些参数 Delivery mode: 是否持久化,1 - Non-persistent,2 - Persistent Headers:Headers can have a ...

  3. Django 高级配置

    目录 Django 信号 信号系统三要素: 信号的分类: Django 内置信号: 具体 Django 信号内容 定义信号 发送信号 接收信号 信号接收器 防止重复信号 Django 内置信号操作步骤 ...

  4. Linux双网卡绑定bond详解

    参考资料: 1.https://blog.csdn.net/shengerjianku/article/details/79221886

  5. rabbitmq 从channal获得socket

    std::string queue_name = "hello100"; AmqpClient::Channel::ptr_t channel = AmqpClient::Chan ...

  6. jquery 小知识

    $("p:eq(0)") :表p标签的第一个元素 $("p:eq(1)") :表p标签的第二个元素

  7. HIbernate 查询拼接参数

    public List<TrailTestModel> findByEid(List<String> trailids, String eid) { // TODO Auto- ...

  8. jquery对象中 “冒号” 详解

      冒号  可以理解为 “匹配” 或 “选取”的意思.   $(":button") 表示匹配所有的按钮.$("input:checked")表示匹配所有选中的 ...

  9. leetcode简单刷题

    [python3]参数中的冒号与箭头 冒号后面是建议传入的参数类型 箭头后面是建议函数返回的类型

  10. 线程join方法 小demo

    1.第一个示例: package cn.threaddemo; public class T implements Runnable { public static int a = 0; @Overr ...