(Development Support Class Library) ThreadLocal Class

ThreadLocal类

To understand the role of ThreadLocal class objects, first write a simple program to watch:

package 开发支持类库;

public class ThreadLocal类 {
	public static void main(String[] args) {
		Message msg = new Message();//实例化消息主体对象
		msg.setInfo("这是一个消息内容");//设置发送的消息内容
		Channel.setMessage(msg);//设置发送的消息
		Channel.send();//发送
	}
}

//发送的消息体
class Message{
	private String info;
	
	public void setInfo(String info) {
		this.info = info;
	}
	
	public String getInfo() {
		return info;
	}
}

//消息的发送通道
class Channel{
	private static Message message;
	
	public static void setMessage(Message m) {
		message = m;
	}
	
	//发送消息
	public static void send() {
		System.out.println("【消息发送】"+message.getInfo());
	}
}

[Message sending] This is a message content

The current program is actually processed in a single-threaded mode. So if in the state of multithreading can achieve consistent operation effects? To this end, three threads will be started for processing.

Example: The impact of multithreading

package 开发支持类库;

public class ThreadLocal类 {
	public static void main(String[] args) {
		//创建三个线程,利用Lambda表示式直接覆写run()方法
		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 Message{
	private String info;
	
	public void setInfo(String info) {
		this.info = info;
	}
	
	public String getInfo() {
		return info;
	}
}

//消息的发送通道
class Channel{
	private static Message message;
	
	public static void setMessage(Message m) {
		message = m;
	}
	
	//发送消息
	public static void send() {
		System.out.println(Thread.currentThread().getName()+"【消息发送】"+message.getInfo());
	}
}

(The result is not fixed)

Message sender A [message sending] message content of the second thread Message
sender B [message sending] message content of the second thread
Message sender C [message sending] message content of the third thread

At this time, the processing of the message has an impact. The main reason is that the three threads have to set the info of the Message, and the first thread has just set it and has not sent it, and the second thread has modified it.

While keeping the core structure of the Channel (all sent channels) unchanged, it is necessary to consider the independent operation of each thread. In this case, it is found that in addition to retaining the sent messages, the Channel should also Store the mark of each thread (current thread), then at this time you can store data through the ThreadLocal class. The following methods are provided in the ThreanLocal class:

  • Construction method: public ThreadLocal();
  • Set data: public void set();
  •  Take out the data: public T get();
  • Delete data: public void remove();

Use ThreadLocal class to store objects, it can store the current thread object and data object at the same time, so as to ensure that the current thread object corresponds to the current data object.

 

Example: Solve the problem of thread synchronization

package 开发支持类库;

public class ThreadLocal类 {
	public static void main(String[] args) {
		//创建三个线程,利用Lambda表示式直接覆写run()方法
		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 Message{
	private String info;
	
	public void setInfo(String info) {
		this.info = info;
	}
	
	public String getInfo() {
		return info;
	}
}

//消息的发送通道
class Channel{
	private static ThreadLocal<Message> THREADLOCAL = new ThreadLocal<Message>();//创建一个用来存储Message类型数据的ThreadLocal对象
	
	public static void setMessage(Message m) {
		THREADLOCAL.set(m);//向ThreadLocal保存数据,会把当前线程对象也存储起来。
	}
	
	//发送消息
	public static void send() {
		System.out.println(Thread.currentThread().getName()+"【消息发送】"+THREADLOCAL.get().getInfo());//根据线程的当前对象取出Message对象执行getInfo()
	}
}

Message sender C [message sending] message content of the third thread
Message sender B [message sending] message content of the second thread
Message sender A [message sending] message content of the first thread

Each thread can only save one data through ThreadLocal, which can be understood as: key (current thread) corresponds to a value (data object).

Guess you like

Origin blog.csdn.net/weixin_46245201/article/details/112598870