ThreadLocal使用

package com.fll.threadlocal;

/**
 * ThreadLocal -- 线程局部变量  
 * 一个线程安全的工具类,代表了一个线程局部变量,通过把数据放入ThreadLocal中就可以为每个线程创建一个该变量的副本,从而避免并发访问中线程的安全问题。
 * 用法:
 * T get():返回ThreadLocal中当前线程副本的值
 * void remove(): 删除ThreadLocal中当前线程副本的值
 * void set(T value):设置ThreadLocal中当前线程副本的值
 * 
 * 通常建议:如果多个线程之间需要共享资源,已达到线程之间的通信功能,就是用同步机制;
 * 如果需要隔离多个线程之间的共享冲突,则可以使用ThreadLocal.
 */
public class ThreadLocal_Test01 {

	public static void main(String[] args) {
		//启动两个线程,连个线程共享一个Account
		Account account = new Account("初始名");
		
		/*
		 * 虽然两个线程共享同一个账户,即只有一个账户名,
		 * 但是由于账户名是ThreadLocal类型的,所以每个线程都拥有各自的账户名副本,
		 * 因此,在i==6之后,将看到两个线程访问年同一个账户时出现放入不同账户名
		 */
		new MyTest(account,"线程A").start();
		new MyTest(account,"线程B").start();
	}
}


class Account{
	/*定义一个ThreadLocal类型的变量,该变量将是一个线程局部变量,每个线程都会保存改变量的一个副本*/
	private ThreadLocal<String> name = new ThreadLocal<>();
	
	//定义一个初始化name成员变量的构造器
	public Account(String str){
		setName(str);
		//下面用于访问当前线程的name副本的值
		System.out.println("ThreadLocal 变量: "+this.name.get());
	}

	public String getName() {
		return name.get();
	}

	public void setName(String value) {
		this.name.set(value);;
	}
}

class MyTest extends Thread{

	private Account account;
	
	public MyTest(Account account,String name) {
		this.account = account;
//		this.account.setName(name);
//		super(name);
	}
	
	@Override
	public void run() {
//		super.run();
		for (int i = 0; i < 10; i++) {
			//当i == 6时输出将账户名替换成当前线程名
			if(i == 6) {
//				System.out.println("getName(): "+getName());
				account.setName(getName());
			}
			
			//输出同一个账户的账户名和循环变量
			System.out.println(account.getName()+"账户i的值: "+i);
		}
	}
}

输出:

posted @ 2021-03-04 14:29  方罗良  阅读(59)  评论(0)    收藏  举报