ThreadLocal 类
Para entender a função dos objetos da classe ThreadLocal, primeiro escreva um programa simples para observar:
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());
}
}
[Envio de mensagem] Este é um conteúdo de mensagem
O programa atual é realmente processado em um modo de thread único. Então, se no estado de multithreading pode alcançar efeitos de operação consistentes? Para tanto, três threads serão iniciados para processamento.
Exemplo: o impacto do 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());
}
}
(O resultado não é fixo)
Remetente da mensagem A [envio de mensagem] conteúdo da mensagem do segundo tópico
Remetente da mensagem B [envio de mensagem] conteúdo da mensagem do segundo tópico
Remetente da mensagem C [envio de mensagem] conteúdo da mensagem do terceiro tópico
Neste momento, o processamento da mensagem tem um impacto. O principal motivo é que os três tópicos têm que definir as informações da Mensagem, e o primeiro tópico acaba de defini-la e não a enviou, e o segundo tópico foi modificado isto.
Mantendo inalterada a estrutura central do Canal (todos os canais enviados), é necessário considerar o funcionamento independente de cada thread. Neste caso, verifica-se que além de reter as mensagens enviadas, o Canal também deve armazenar a marca de cada thread (thread atual), então neste momento você pode armazenar dados por meio da classe ThreadLocal. Os seguintes métodos são fornecidos na classe ThreanLocal:
- Método de construção: public ThreadLocal ();
- Dados do conjunto: public void set ();
- Retire os dados: public T get ();
- Excluir dados: public void remove ();
Use a classe ThreadLocal para armazenar objetos, ela pode armazenar o objeto de thread atual e o objeto de dados ao mesmo tempo, de modo a garantir que o objeto de thread atual corresponda ao objeto de dados atual.
Exemplo: Resolva o problema de sincronização de threads
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()
}
}
Remetente da mensagem C [envio de mensagem] conteúdo da mensagem do terceiro encadeamento
Remetente da mensagem B [envio de mensagem] conteúdo da mensagem do segundo encadeamento
Remetente da mensagem A [envio de mensagem] conteúdo da mensagem do primeiro encadeamento
Cada thread só pode salvar um dado por meio de ThreadLocal, que pode ser entendido como: chave (thread atual) corresponde a um valor (objeto de dados).