1. 程式人生 > >4.2執行緒區域性變數(Thread-Local Variables)

4.2執行緒區域性變數(Thread-Local Variables)

    你有時候想要通過每個執行緒的資料(如一個使用者的ID)連線一個執行緒。儘管你可以使用區域性變數完成這個任務,僅僅只有區域性變數存在時你才可以這樣做。你可以用一個例項的欄位去長久儲存這個資料,但是你需要去處理同步。幸好,Java提供了java.lang.ThreadLocal類作為一個簡的替換使用。
    每個ThreadLocal例項是一個執行緒區域性變數(Thread-Local Variables),這個區域性變數為每個訪問變數的執行緒提供單獨的儲存槽。你可以認為一個執行緒區域性變數是一個多槽的變數,在它的每個執行緒裡可以儲存相同變數的不同值。每個執行緒只關注自己的值,和不關注其它執行緒它們自己的值在這變數中。
     ThreadLocal的宣告是ThreadLocal<T>,這個T是指示值的型別用於儲存在這個變數中。這個類聲明瞭如下的構造器和方法:
        (1)ThreadLocal:建立一個新的執行緒區域性變數。
        (2) T get():在請求執行緒儲存槽中返回值。當執行緒請求這個方法,而執行緒儲存槽不存在,那麼get()會去請求initialValue()方法。
        (3)T initialValue():建立請求執行緒儲存槽,和儲存預設值在這個儲存槽。這個初始值是null。你必須建立ThreadLocal的子類,並重寫它的protected方法去提供更多有效的值。
        (4)void remove():移除請求執行緒儲存槽。如果這個方法呼叫get()卻沒使用set()。那麼這個get()會呼叫initialValue()方法。
            void set(T value):將值放入到請求執行緒儲存槽。

      Listing4-3展示瞭如何使用ThreadLocal去連線兩個執行緒的不同使用者IDs

package com.owen.thread.chapter4;

public class ThreadLocalDemo
{

	private static volatile ThreadLocal<String> userID = new ThreadLocal<String>();

	public static void main(String[] args)
	{
		Runnable r = new Runnable()
		{
			@Override
			public void run()
			{
				String name = Thread.currentThread().getName();
				if (name.equals("A"))
					userID.set("foxtrot");
				else
					userID.set("charlie");
				System.out.println(name + " " + userID.get());
			}
		};
		Thread thdA = new Thread(r);
		thdA.setName("A");
		Thread thdB = new Thread(r);
		thdB.setName("B");
		thdA.start();
		thdB.start();
	}
}
    之後例項化ThreadLocal和定義一個引用volatile的全域性類命名為userID(這個全域性是一個volatile因為它需要通過不同的執行緒,它可能在多處理器或多核機器上執行——用它代替final),預設主執行緒建立兩個或多執行緒,它儲存不同的java.lang.String.object在userID中,和輸出它們的物件。
   執行上面的程式碼,你將會看到:
A foxtrot
B charlie
     值儲存線上程區域性變數中,而這些值之間沒有聯絡。當一個新的執行緒被建立,它獲取一個新的儲存槽包含initialValue()的值。可能你需要涉及來自一個父執行緒(a parent thread)的值,一個執行緒建立另一個執行緒,給一個子執行緒,這個執行緒是建立過的。你可以用InheritableThreadLocal來完成任務。
  InheritableThreadLocal是ThreadLocal的一個子類。下面也就是我們所知道的InheritableThreadLocal的構造器:
      (1)T childValue(T parentValue):計運算元類的初始值作為一個父值的應用,這個時候子執行緒被建立。在子執行緒被建立之前這個方法從父執行緒中請求。這個方法從parentValue中返回引數,和當其它值被要求時這個方法需要重寫。
     Listing4-4展示如何運用InheritableThreadLocal通過父執行緒的Integer物件給子執行緒。
      Listing4-4通過父執行緒的物件給一個子執行緒。
package com.owen.thread.chapter4;

public class InheritableThreadLocalDemo
{

	private static final InheritableThreadLocal<Integer> intVal = new InheritableThreadLocal<Integer>();

	public static void main(String[] args)
	{
		Runnable rP = () -> {
			intVal.set(new Integer(10));
			Runnable rC = () -> {
				Thread thd = Thread.currentThread();
				String name = thd.getName();
				System.out.printf("%s %d%n", name, intVal.get());
			};
			Thread thdChild = new Thread(rC);
			thdChild.setName("Child");
			thdChild.start();
		};
		new Thread(rP).start();
	}

}
     之後初始化InheritableThreadLocal和定義它為final類的變數(也可以用volatile替代)命名為intVal,這個預設執行緒建立一個父執行緒,它儲存一個java.lang.Integer物件包含值為10在intVal變數中。這個父執行緒建立一個子執行緒,它呼叫intVal和接收它的父執行緒的Integer物件。執行上面程式碼你將會看到:Child 10。
 原始碼下載:[email protected]:owenwilliam/Thread.git

相關推薦

4.2執行區域性變數Thread-Local Variables

    你有時候想要通過每個執行緒的資料(如一個使用者的ID)連線一個執行緒。儘管你可以使用區域性變數完成這個任務,僅僅只有區域性變數存在時你才可以這樣做。你可以用一個例項的欄位去長久儲存這個資料,但是你需要去處理同步。幸好,Java提供了java.lang.ThreadL

Python學習總結筆記4--執行區域性變數之Threading.local

當我們使用執行緒的時候,能使用執行緒的區域性變數,就儘量不要用全域性變數,因為使用全域性變數涉及同步的問題(參見我的上一篇部落格Python學習總結筆記(3)–多執行緒與執行緒同步 )。 使用區域性變數的時候,需要傳遞引數,比如有這樣一個例子,程式需要處理客戶

JAVA基礎23-多執行執行區域性變數和未捕獲異常處理器】

一、執行緒區域性變數    線上程中使用共享變數肯定是存在風險。為了規避這個風險,利用同步機制,volatile這些方法都可以。但是也可為每個執行緒分配一個變數。使用ThreadLocal輔助類為各個執行緒提供各自的例項。  ThreadLocal為每個使用

淺談Flask 中的 執行區域性變數 request 原理

在多執行緒伺服器中客戶端每建立一個連結,伺服器就建立一個執行緒,每個執行緒中就會有一個request來表示客戶端的連結請求資訊。 不同的使用者訪問flask伺服器.都有自己的request. 使用者A------------執行緒A-------------> request

執行區域性變數的使用ThreadLocal和其底層原理

/*ThreadLocal類:   * 該類提供了執行緒區域性變數,它是一個池 Map<Thread.currentThread,locObj>,  * 池中為每個執行緒儲存一個獨立的區域性變數,  * 每個執行緒可以從這個池中讀取或設定自己的區域性變數。 //

eclipse/cdt:-fPIC引起的執行區域性變數(__thread)的SIGSEGV異常問題

最近在 ubuntu下用eclipse Neon.3 (4.6.3) 除錯一個C工程時遇到一個好奇怪的問題: 一個應用程式A,呼叫一個靜態庫B,靜態庫中用__thread定義了執行緒區域性變數(TLS,thread local storage),在eclip

31-執行區域性變數 ThreadLocal

執行緒區域性變數 ThreadLocal 原理,作用 每個Thread維護一個ThreadLocalMap 對映表,使用ThreadLocal物件為弱引用的map集合(即弱引用的物件可以在GC中被回收掉),value為對應的值。其生命週期和執行緒一致。

執行親和性Thread Affinity

原文連結 譯者:裘卡 如果你正在開發低延遲的網路應用,那應該對執行緒親和性(Thread affinity)有所瞭解。執行緒親和效能夠強制使你的應用執行緒執行在特定的一個或多個cpu上。通過這種方式,可以消除作業系統進行排程過程導致執行緒遷移所造成的影響。幸運的是,剛好有一個這麼一個java

執行區域性儲存TLS)

1.      執行緒區域性儲存(TLS)是簡單的儲存執行緒區域性資料的系統。 2.      利用TLS可以為每個程序關聯一個數據。一般來說,為執行緒分配TLS索引在主執行緒中完成,而分配的索引值應儲存在全域性變數中。 3.      使用到的函式介紹: 1)      主執行緒呼叫TlsAlloc為執行

執行的禮讓Thread.yield()方法

在多執行緒裡面有各種各樣的方法,其中有一個禮讓的方法很有意思,現實生活中所謂的禮讓,就是“委屈自己方便他人”!比如過馬路,汽車禮讓行人,當然這是在國外,國內過個斑馬線是要看司機的性格的!那麼線上程中是

高併發下的執行安全實現——執行區域性變數

今天我們來討論另外一種執行緒安全的實現方法。如果說互斥同步是多執行緒間的資料共享,那麼執行緒區域性變數就是執行緒間的資料隔離。ThreadLocal把共享資料的可見範圍限制在同一個執行緒之內,這樣無須同步也能實現執行緒之間資料不爭用的問題。當使用ThreadLo

ThreadLocal 執行區域性變數

ThreadLocal 一、概念 ThreadLocal是Thread Local Variable(執行緒區域性變數)的意思。執行緒區域性變數的功能是為每一個使用該變數的執行緒都提供一個變數值的副本,使每一個執行緒都可以獨立的改變自己的副本,而不會和其他執行緒的副本衝突

執行執行區域性變數ThreadLocal及原理

一、執行緒區域性變數ThreadLocal ThreadLocal為變數在每個執行緒中都建立了一個副本,那麼每個執行緒可以訪問自己內部的副本變數。既然是隻有當前執行緒可以訪問的資料,自然是執行緒安全的。 主要方法: initialValue()方法可以重寫,它預設是返回

iOS開發-多執行程式設計技術Thread、Cocoa operations、GCD

簡介 在軟體開發中,多執行緒程式設計技術被廣泛應用,相信多執行緒任務對我們來說已經不再陌生了。有了多執行緒技術,我們可以同做多個事情,而不是一個一個任務地進行。比如:前端和後臺作互動、大任務(需要耗費一定的時間和資源)等等。也就是說,我們可以使用執行緒把佔據時間長的任務放到後臺中處理,而不影響到使用者的使用

android執行管理二Thread

前言 一 結構關係 publicclassThreadimplementsRunnable{ ...... } 很顯然Thread繼承了Runnable。 Runnable原始碼如下: pub

【Java多執行】共享變數&同步-非同步容器&執行區域性變數

共享變數 (Volatile Atomic) volatile:當多個執行緒訪問一個成員變數的時候,需要這個變數在多個執行緒中可見。 Atomic:Atomic方法對該變數的操作是原子性操作,顆粒度是到對這個變數的一次操作。 private stati

每天進步一點點——Linux中的執行區域性儲存

凡是帶有__thread的變數,每個執行緒都擁有該變數的一份拷貝,且互不干擾。執行緒區域性儲存中的變數將一直存在,直至執行緒終止,當執行緒終止時會自動釋放這一儲存。__thread並不是所有資料型別都可以使用的,因為其只支援POD(Plain old data structure)[1]型別,不支援clas

執行-區域性變數和成員變數

Java多執行緒對成員變數和區域性變數的影響 最近複習了一下Java多執行緒的一些基礎的礎知識,這裡演示一個java多執行緒對成員變數和區域性變數的Demo 對區域性變數的操作: /** * Java區域性變數和成員變數程式碼演示 */ publi

理解ThreadLocal(執行區域性變數)

ThreadLocal(執行緒區域性變數)概述 ThreadLocal是什麼呢?其實ThreadLocal並非是一個執行緒的本地實現版本,它並不是一個Thread,而是threadlocalvariable(執行緒區域性變數)。也許把它命名為ThreadLocalVa

Java中執行區域性變數ThreadLocal使用教程及原始碼分析

       在Java多執行緒程式設計中有時候會遇見執行緒本地區域性變數ThreadLocal這個類,下面就來講講ThreadLocal的使用及原始碼分析。        ThreadLocal 是Thread Local Varial(執行緒區域性變數)的意思,每個執行