這個在Java中的ThreadLocal類別可以保證讓你建立的變數只能被相同的執行緒讀寫。因此,甚至如果兩個執行緒正在執行相同的程式碼,而這個程式碼有一個對於ThreadLocal變數的引用,然後這兩個執行緒就不能看到彼此的ThreadLocal變數。
建立一個ThreadLocal
這裡有一個程式碼現實如何建立一個ThreadLocal:
private ThreadLocal myThreadLocal = new ThreadLocal();
如你看到的,你實例化一個新的ThreadLocal物件。這個每個線程只需要做一次。甚至如果不同的執行緒執行存取一個ThreadLocal的相同的程式碼,每一個執行緒只會看到它自己的ThreadLocal實例。甚至如果兩個執行緒設定不同的值在這相同的ThreadLocal物件上,它們都不會看到彼此的值。
存取一個ThreadLocal
一旦一個ThreadLocal被建立了,你就可以像下面這樣設定一個值去儲存:
myThreadLocal.set("A thread local value");
你可以像下面這樣去讀這個值:
String threadLocalValue = (String) myThreadLocal.get();
這個get方法回傳一個對象,而這個set方法傳遞一個物件作為參數。
泛型化的ThreadLocal
你可以建立一個泛型化的ThreadLocal,以至於你不用在呼叫get方法的時候進行強制轉化了。這裡有一個例子:
private ThreadLocal<String> myThreadLocal = new ThreadLocal<String>();
現在你只能儲存儲存字串類型在ThreadLocal實例中。另外的,你不需要強制轉換這個值了:
myThreadLocal.set("Hello ThreadLocal"); String threadLocalValue = myThreadLocal.get();
初始化ThreadLocal值
因為設定一個ThreadLocal物件的值只是對於設定這個值的執行緒可見的,所以沒有執行緒可以使用set方法設定ThreadLocal的值對所有的執行緒可見。
取代的,你可以透過子類別ThreadLocal特指一個初始化的值對於一個ThreadLocal對象,以及覆寫initialValue方法。像下面這樣:
private ThreadLocal myThreadLocal = new ThreadLocal<String>() { @Override protected String initialValue() { return "This is the initial value"; } };
現在所有的執行緒可以看到相同的初始化值,在呼叫set方法之前。
完整的ThreadLocal實例
這裡有一個完整運行的ThreadLocal實例
public class ThreadLocalExample { public static class MyRunnable implements Runnable { private ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(); @Override public void run() { threadLocal.set( (int) (Math.random() * 100D) ); try { Thread.sleep(2000); } catch (InterruptedException e) { } System.out.println(threadLocal.get()); } } public static void main(String[] args) { MyRunnable sharedRunnableInstance = new MyRunnable(); Thread thread1 = new Thread(sharedRunnableInstance); Thread thread2 = new Thread(sharedRunnableInstance); thread1.start(); thread2.start(); thread1.join(); //wait for thread 1 to terminate thread2.join(); //wait for thread 2 to terminate } }
這個範例創建了一個單獨的MyRunnable實例,它被傳遞給了兩個不同的執行緒。這兩個執行緒都執行了run方法,並且在ThreadLocal實例上設定了不同的值。如果對於這個set方法的呼叫存取是同步的,而且它還沒有使用ThreadLocal對象,第二個執行緒將會覆寫第一個執行緒設定的值。
然而,因為它是一個ThreadLocal對象,不能看到彼此的值。因此,他們設定和得到不同的值。
InheritableThreadLocal
#這個InheritableThreadLocal類別是ThreadLocal類別的子類別。取代的每一個線程在一個ThreadLoca內部都有它自己的值,這個類別同意訪問對於一個線程的值,並且被那個線程創建的所有子線程。
以上就是Java本地線程(ThreadLocal)的內容,更多相關內容請關注PHP中文網(www.php.cn)!