欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

阿里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;
	}
}

阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第12章:开发支持类库:课时49:ThreadLocal类

对于当前的程序实际上采用的是一种单线程的模式来进行处理的。那么如果在多线程的状态下能否实现完全一致的操作呢?为此将启动三个线程进行处理。
范例:多线程的影响

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();
	}
}

这个时候消息的处理产生了影响。
阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第12章:开发支持类库:课时49:ThreadLocal类
在保持Channel(所有发送的通道)核心结构不改变的情况下,需要考虑到每个线程的独立操作问题。那么在这样的情况下就发现对于Channel类而言除了要保留有发送的消息之外,还应该多存放有一个每一个线程的标记(当前线程),那么这个时候可以通过ThreadLocal类来存放数据。在ThreadLocal类里面提供有如下的操作方法:
构造方法:public ThreadLocal();
设置数据:public void set(T value);
取出数据:public T get();
删除数据:public void remove();
阿里Java学习路线:阶段 1:Java语言基础-Java语言高级特性:第12章:开发支持类库:课时49:ThreadLocal类
范例:解决线程同步问题

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只允许保存一个数据 。

推荐阅读