ThreadLoal的使用

      ThreadLocal是Java爲線程安全提供的工具類,它代表一個線程局部變量,通過把數據放到ThreadLocal中可以讓線程創建一個該變量的副本,從而避免併發訪問的線程安全問題。

下面是對該類的使用:

class Account
{
	/* 定義一個ThreadLocal類型的變量,該變量將是一個線程局部變量
	每個線程都會保留該變量的一個副本 */
	private ThreadLocal<String> name = new ThreadLocal<>();
	// 定義一個初始化name成員變量的構造器
	public Account(String str)
	{
		this.name.set(str);
		// 下面代碼用於訪問當前線程的name副本的值
		System.out.println("---" + this.name.get());
	}
	// name的setter和getter方法
	public String getName()
	{
		return name.get();
	}
	public void setName(String str)
	{
		this.name.set(str);
	}
}
class MyTest extends Thread
{
	// 定義一個Account類型的成員變量
	private Account account;
	public MyTest(Account account, String name)
	{
		super(name);
		this.account = account;
	}
	public void run()
	{
		// 循環10次
		for (int i = 0 ; i < 10 ; i++)
		{
			// 當i == 6時輸出將賬戶名替換成當前線程名
			if (i == 6)
			{
				account.setName(getName());
			}
			// 輸出同一個賬戶的賬戶名和循環變量
			System.out.println(account.getName()
				+ " 賬戶的i值:" + i);
		}
	}
}
public class ThreadLocalTest
{
	public static void main(String[] args)
	{
		// 啓動兩條線程,兩條線程共享同一個Account
		Account at = new Account("初始名");
		/*
		雖然兩條線程共享同一個賬戶,即只有一個賬戶名
		但由於賬戶名是ThreadLocal類型的,所以每條線程
		都完全擁有各自的賬戶名副本,所以從i == 6之後,將看到兩條
		線程訪問同一個賬戶時看到不同的賬戶名。
		*/
		new MyTest(at , "線程甲").start();
		new MyTest(at , "線程乙").start ();
	}
}
      運行上面代碼會發現三個線程之間互不干擾,每個線程都完全擁有自己的ThreadLocal變量。ThreadLocal和其他所有的同步機制一樣,是爲了解決多線程中對同一變量的訪問衝突,解決了多線程的併發訪問,單並不能代替同步機制,兩者面對的問題領域不同。同步機制是爲了同步多個線程對相同資源的併發訪問,先多個線程之間進行通訊的有效方式;而ThreadLocal是爲了隔離多個線程的數據共享,避免線程之間對共享資源的進程,不存在線程同步的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章