To really understand the role of the ThreadLocal class, let's write a simple program to do a preliminary analysis
Example: (Now define a structure like this)
package com.java.springtest.test; /** * @author Woo_home * @create by 2020/1/22 */ class Message { // Message body to send private String info; public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } } class Channel { // Message Sending Channel private static Message message; public Channel() { } public static void setMessage(Message msg) { message = msg; } public static void send() { // send message System.out.println("[Message Sending)" + message.getInfo()); } } public class Demo2 { public static void main(String[] args) { Message message = new Message(); // Instantiate message body object message.setInfo("www.baidu.com");// Set up what to send Channel.setMessage(message); // Set the message to send Channel.send(); // Send out } }
The current program is actually handled in a single-threaded mode.Can consistent operations be accomplished in a multithreaded state?For this we will start three threads to process
Example: (Multithreaded impact)
package com.java.springtest.test; /** * @author Woo_home * @create by 2020/1/22 */ class Message { // Message body to send private String info; public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } } class Channel { // Message Sending Channel private static Message message; public Channel() { } public static void setMessage(Message msg) { message = msg; } public static void send() { // send message System.out.println("[" + Thread.currentThread().getName() + "Message Sending)" + message.getInfo()); } } public class Demo2 { public static void main(String[] args) { new Thread(() -> { Message message = new Message(); // Instantiate message body object message.setInfo("Message for the first thread");// Set up what to send Channel.setMessage(message); // Set the message to send Channel.send(); },"message sender A").start(); new Thread(() -> { Message message = new Message(); // Instantiate message body object message.setInfo("Messages from the second thread");// Set up what to send Channel.setMessage(message); // Set the message to send Channel.send(); },"message sender B").start(); new Thread(() -> { Message message = new Message(); // Instantiate message body object message.setInfo("Messages from the third thread");// Set up what to send Channel.setMessage(message); // Set the message to send Channel.send(); },"message sender C").start(); } }
This time the processing of the message has an impact, B sent the C message, of course, you may execute a few more times A sent the B message, you can practice it yourself
Keeping the core structure of Channel (all send channels) unchanged, you need to consider the independent operation of each thread. In this case, you can find that for Channel classes, in addition to keeping the sent messages, you should also store a flag for each thread (the current thread), so you can Thread it at this time.Local class to store data.Within the ThreadLocal class, the following operations are provided:
- Construction method: public ThreadLocal()
- Set data: public void set(T value)
- Take out the data: public T get()
- Delete data: public void remove()
Example: (Resolve thread synchronization issues)
package com.java.springtest.test; /** * @author Woo_home * @create by 2020/1/22 */ class Message { // Message body to send private String info; public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } } class Channel { // Message Sending Channel private static final ThreadLocal<Message> THREAD_LOCAL_MESSAGE = new ThreadLocal<>(); public Channel() { } public static void setMessage(Message msg) { THREAD_LOCAL_MESSAGE.set(msg); // Save data to ThreadLocal } public static void send() { // send message // Get data from ThreadLocal System.out.println("[" + Thread.currentThread().getName() + "Message Sending)" + THREAD_LOCAL_MESSAGE.get().getInfo()); } } public class Demo2 { public static void main(String[] args) { new Thread(() -> { Message message = new Message(); // Instantiate message body object message.setInfo("Message for the first thread");// Set up what to send Channel.setMessage(message); // Set the message to send Channel.send(); },"message sender A").start(); new Thread(() -> { Message message = new Message(); // Instantiate message body object message.setInfo("Messages from the second thread");// Set up what to send Channel.setMessage(message); // Set the message to send Channel.send(); },"message sender B").start(); new Thread(() -> { Message message = new Message(); // Instantiate message body object message.setInfo("Messages from the third thread");// Set up what to send Channel.setMessage(message); // Set the message to send Channel.send(); },"message sender C").start(); } }
Output: There will be no asynchronization at this time
Simply put: Each thread allows only one data to be saved through ThreadLocal