阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第12章:开发支持类库:课时49:ThreadLocal类
程序员文章站
2022-07-04 19:10:02
...
在真正去了解ThreadLocal类作用的时候下面编写一个简单的程序做一个先期的分析。
范例:现在定义这样的一个结构
package cn.mldn.demo;
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
Message msg = new Message(); // 实例化消息主体对象
msg.setInfo("www.mldn.cn"); // 设置要发送的内容
Channel.setMessage(msg); // 设置要发送的消息
Channel.send();
}
}
class Channel { // 消息的发送通道
private static Message message;
private Channel() {}
public static void setMessage(Message m) {
message = m ;
}
public static void send() { // 发送消息
System.out.println("消息发送" + message.getInfo());
}
}
class Message { // 要发送的消息体
private String info ;
public void setInfo(String info) {
this.info = info;
}
public String getInfo() {
return info;
}
}
对于当前的程序实际上采用的是一种单线程的模式来进行处理的。那么如果在多线程的状态下能否实现完全一致的操作呢?为此将启动三个线程进行处理。
范例:多线程的影响
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
new Thread(()->{
Message msg = new Message(); // 实例化消息主体对象
msg.setInfo("第一个线程的消息"); // 设置要发送的内容
Channel.setMessage(msg); // 设置要发送的消息
Channel.send();
},"消息发送者A").start();
new Thread(()->{
Message msg = new Message(); // 实例化消息主体对象
msg.setInfo("第二个线程的消息"); // 设置要发送的内容
Channel.setMessage(msg); // 设置要发送的消息
Channel.send();
},"消息发送者B").start();
new Thread(()->{
Message msg = new Message(); // 实例化消息主体对象
msg.setInfo("第三个线程的消息"); // 设置要发送的内容
Channel.setMessage(msg); // 设置要发送的消息
Channel.send();
},"消息发送者C").start();
}
}
这个时候消息的处理产生了影响。
在保持Channel(所有发送的通道)核心结构不改变的情况下,需要考虑到每个线程的独立操作问题。那么在这样的情况下就发现对于Channel类而言除了要保留有发送的消息之外,还应该多存放有一个每一个线程的标记(当前线程),那么这个时候可以通过ThreadLocal类来存放数据。在ThreadLocal类里面提供有如下的操作方法:
构造方法:public ThreadLocal();
设置数据:public void set(T value);
取出数据:public T get();
删除数据:public void remove();
范例:解决线程同步问题
package cn.mldn.demo;
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
new Thread(()->{
Message msg = new Message(); // 实例化消息主体对象
msg.setInfo("第一个线程的消息"); // 设置要发送的内容
Channel.setMessage(msg); // 设置要发送的消息
Channel.send();
},"消息发送者A").start();
new Thread(()->{
Message msg = new Message(); // 实例化消息主体对象
msg.setInfo("第二个线程的消息"); // 设置要发送的内容
Channel.setMessage(msg); // 设置要发送的消息
Channel.send();
},"消息发送者B").start();
new Thread(()->{
Message msg = new Message(); // 实例化消息主体对象
msg.setInfo("第三个线程的消息"); // 设置要发送的内容
Channel.setMessage(msg); // 设置要发送的消息
Channel.send();
},"消息发送者C").start();
}
}
class Channel { // 消息的发送通道
private static final ThreadLocal<Message> THREADLOCAL = new ThreadLocal<Message>();
private Channel() {}
public static void setMessage(Message m) {
THREADLOCAL.set(m); ; // 向ThreadLocal中保存数据
}
public static void send() { // 发送消息
System.out.println("【" + Thread.currentThread().getName() + "、消息发送】" + THREADLOCAL.get().getInfo());
}
}
class Message { // 要发送的消息体
private String info ;
public void setInfo(String info) {
this.info = info;
}
public String getInfo() {
return info;
}
}
每一个线程通过ThreadLocal只允许保存一个数据 。
上一篇: 互联网协会点名QQ音乐、快手等14款APP:疑似过度收集个人信息
下一篇: 什么都别说
推荐阅读
-
阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第22章:反射应用案例:课时101:反射实例化对象
-
阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第24章:反射与简单Java类:课时111:单级属性赋值
-
阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第18章: 输入与输出支持:课时84:打印流
-
阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第22章:反射应用案例:课时102:反射与工厂设计模式
-
阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第16章:字节流与字符流:课时75:Writer字符输出流
-
阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第17章: IO操作深入:课时83:RandomAccessFile
-
阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第26章:反射与代理设计模式:课时118:动态代理设计模式
-
阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第23章:反射与类操作:课时105:反射调用构造方法(含关系图-重要)
-
阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第17章: IO操作深入:课时82:管道流
-
阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第25章:ClassLoader类加载器:课时115:ClassLoader类加载器简介