java中的threadlocal類允許我們創建只能被同一個線程讀寫的變量。因此,如果一段代碼含有一個threadlocal變量的引用,即使兩個線程同時執行這段代碼,它們也無法訪問到對方的threadlocal變量。
如何創建threadlocal變量
以下代碼展示了如何創建一個threadlocal變量:
1
|
private threadlocal mythreadlocal = new threadlocal(); |
我們可以看到,通過這段代碼實例化了一個threadlocal對象。我們只需要實例化對象一次,并且也不需要知道它是被哪個線程實例化。雖然所有的線程都能訪問到這個threadlocal實例,但是每個線程卻只能訪問到自己通過調用threadlocal的set()方法設置的值。即使是兩個不同的線程在同一個threadlocal對象上設置了不同的值,他們仍然無法訪問到對方的值。
如何訪問threadlocal變量
一旦創建了一個threadlocal變量,你可以通過如下代碼設置某個需要保存的值:
1
|
mythreadlocal.set("a thread local value”); |
可以通過下面方法讀取保存在threadlocal變量中的值:
1
|
string threadlocalvalue = (string) mythreadlocal.get(); |
get()方法返回一個object對象,set()對象需要傳入一個object類型的參數。
為threadlocal指定泛型類型
我們可以創建一個指定泛型類型的threadlocal對象,這樣我們就不需要每次對使用get()方法返回的值作強制類型轉換了。下面展示了指定泛型類型的threadlocal例子:
1
|
private threadlocal mythreadlocal = new threadlocal<string>(); |
現在我們只能往threadlocal對象中存入string類型的值了。
并且我們從threadlocal中獲取值的時候也不需要強制類型轉換了。
如何初始化threadlocal變量的值
由于在threadlocal對象中設置的值只能被設置這個值的線程訪問到,線程無法在threadlocal對象上使用set()方法保存一個初始值,并且這個初始值能被所有線程訪問到。
但是我們可以通過創建一個threadlocal的子類并且重寫initialvalue()方法,來為一個threadlocal對象指定一個初始值。就像下面代碼展示的那樣:
1
2
3
4
5
6
7
8
9
10
11
|
private threadlocal mythreadlocal = new threadlocal<string>() { @override protected string initialvalue() { return "this is the initial value" ; } }; |
一個完整的threadlocal例子
下面是一個完整的可執行的threadlocal例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
public class threadlocalexample { public static class myrunnable implements runnable { private threadlocal threadlocal = new threadlocal(); @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(); } } |
上面的例子創建了一個myrunnable實例,并將該實例作為參數傳遞給兩個線程。兩個線程分別執行run()方法,并且都在threadlocal實例上保存了不同的值。如果它們訪問的不是threadlocal對象并且調用的set()方法被同步了,則第二個線程會覆蓋掉第一個線程設置的值。但是,由于它們訪問的是一個threadlocal對象,因此這兩個線程都無法看到對方保存的值。也就是說,它們存取的是兩個不同的值。
關于inheritablethreadlocal
inheritablethreadlocal類是threadlocal類的子類。threadlocal中每個線程擁有它自己的值,與threadlocal不同的是,inheritablethreadlocal允許一個線程以及該線程創建的所有子線程都可以訪問它保存的值。
以上所述是小編給大家介紹的java threadlocal的設計理念與作用詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!
原文鏈接:https://blog.csdn.net/u011860731/article/details/48733073