(Biblioteca de classes de suporte ao desenvolvimento) Classe ThreadLocal

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).

Acho que você gosta

Origin blog.csdn.net/weixin_46245201/article/details/112598870
Recomendado
Clasificación