<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Dict.CN 在線詞典, 英語學習, 在線翻譯

    都市淘沙者

    荔枝FM Everyone can be host

    統計

    留言簿(23)

    積分與排名

    優秀學習網站

    友情連接

    閱讀排行榜

    評論排行榜

    Java中ThreadLocal的設計與使用

    早在Java 1.2推出之時,Java平臺中就引入了一個新的支持:java.lang.ThreadLocal,給我們在編寫多線程程序時提供了一種新的選擇。使用這個工具類可以很簡潔地編寫出優美的多線程程序,雖然ThreadLocal非常有用,但是似乎現在了解它、使用它的朋友還不多。

    ThreadLocal是什么

    ThreadLocal并非是一個線程的本地實現版本,它并不是一個Thread,而是thread local variable(線程局部變量)。也許把它命名為ThreadLocalVar更加合適。線程局部變量(ThreadLocal)其實的功用非常簡單,就是為每一個使用該變量的線程都提供一個變量值的副本,是每一個線程都可以獨立地改變自己的副本,而不會和其它線程的副本沖突。從線程的角度看,就好像每一個線程都完全擁有該變量。線程局部變量并不是Java的新發明,在其它的一些語言編譯器實現(如IBM XL FORTRAN)中,它在語言的層次提供了直接的支持。因為Java中沒有提供在語言層次的直接支持,而是提供了一個ThreadLocal的類來提供支持,所以,在Java中編寫線程局部變量的代碼相對比較笨拙,這也許是線程局部變量沒有在Java中得到很好的普及的一個原因吧。


    ThreadLocal的設計

    首先看看ThreadLocal的接口:

    Object get() ;

    // 返回當前線程的線程局部變量副本 protected Object initialValue(); // 返回該線程局部變量的當前線程的初始值

    void set(Object value);

    // 設置當前線程的線程局部變量副本的值


    ThreadLocal有3個方法,其中值得注意的是initialValue(),該方法是一個protected的方法,顯然是為了子類重寫而特意實現的。該方法返回當前線程在該線程局部變量的初始值,這個方法是一個延遲調用方法,在一個線程第1次調用get()或者set(Object)時才執行,并且僅執行1次。ThreadLocal中的確實實現直接返回一個null:

    protected Object initialValue() { return null; }

    ThreadLocal是如何做到為每一個線程維護變量的副本的呢?其實實現的思路很簡單,在ThreadLocal類中有一個Map,用于存儲每一個線程的變量的副本。比如下面的示例實現:
     1public class ThreadLocal
     2
     3{
     4
     5private Map values = Collections.synchronizedMap(new HashMap());
     6
     7public Object get()
     8
     9{
    10
    11Thread curThread = Thread.currentThread();
    12
    13Object o = values.get(curThread);
    14
    15if (o == null && !values.containsKey(curThread))
    16
    17{
    18
    19= initialValue();
    20
    21values.put(curThread, o);
    22
    23}

    24
    25return o;
    26
    27}

    28
    29
    30public void set(Object newValue)
    31
    32{
    33
    34values.put(Thread.currentThread(), newValue);
    35
    36}

    37
    38
    39public Object initialValue()
    40
    41{
    42
    43return null;
    44
    45}

    46
    47}

    48
    49


    當然,這并不是一個工業強度的實現,但JDK中的ThreadLocal的實現總體思路也類似于此。


    ThreadLocal的使用


    如果希望線程局部變量初始化其它值,那么需要自己實現ThreadLocal的子類并重寫該方法,通常使用一個內部匿名類對ThreadLocal進行子類化,比如下面的例子,SerialNum類為每一個類分配一個序號:
     1
     2public class SerialNum
     3
     4{
     5
     6// The next serial number to be assigned
     7
     8
     9private static int nextSerialNum = 0;
    10
    11private static ThreadLocal serialNum = new ThreadLocal()
    12
    13{
    14
    15protected synchronized Object initialValue()
    16
    17{
    18
    19return new Integer(nextSerialNum++);
    20
    21}

    22
    23}
    ;
    24
    25
    26public static int get()
    27
    28{
    29
    30return ((Integer) (serialNum.get())).intValue();
    31
    32}

    33
    34}

    35


    SerialNum類的使用將非常地簡單,因為get()方法是static的,所以在需要獲取當前線程的序號時,簡單地調用:


    int serial = SerialNum.get();


    即可。


    在線程是活動的并且ThreadLocal對象是可訪問的時,該線程就持有一個到該線程局部變量副本的隱含引用,當該線程運行結束后,該線程擁有的所以線程局部變量的副本都將失效,并等待垃圾收集器收集。


    ThreadLocal與其它同步機制的比較

    ThreadLocal和其它同步機制相比有什么優勢呢?ThreadLocal和其它所有的同步機制都是為了解決多線程中的對同一變量的訪問沖突,在普通的同步機制中,是通過對象加鎖來實現多個線程對同一變量的安全訪問的。這時該變量是多個線程共享的,使用這種同步機制需要很細致地分析在什么時候對變量進行讀寫,什么時候需要鎖定某個對象,什么時候釋放該對象的鎖等等很多。所有這些都是因為多個線程共享了資源造成的。ThreadLocal就從另一個角度來解決多線程的并發訪問,ThreadLocal會為每一個線程維護一個和該線程綁定的變量的副本,從而隔離了多個線程的數據,每一個線程都擁有自己的變量副本,從而也就沒有必要對該變量進行同步了。ThreadLocal提供了線程安全的共享對象,在編寫多線程代碼時,可以把不安全的整個變量封裝進ThreadLocal,或者把該對象的特定于線程的狀態封裝進ThreadLocal。


    由于ThreadLocal中可以持有任何類型的對象,所以使用ThreadLocal get當前線程的值是需要進行強制類型轉換。但隨著新的Java版本(1.5)將模版的引入,新的支持模版參數的ThreadLocal類將從中受益。也可以減少強制類型轉換,并將一些錯誤檢查提前到了編譯期,將一定程度地簡化ThreadLocal的使用。


    總結

    當然ThreadLocal并不能替代同步機制,兩者面向的問題領域不同。同步機制是為了同步多個線程對相同資源的并發訪問,是為了多個線程之間進行通信的有效方式;而ThreadLocal是隔離多個線程的數據共享,從根本上就不在多個線程之間共享資源(變量),這樣當然不需要對多個線程進行同步了。所以,如果你需要進行多個線程之間進行通信,則使用同步機制;如果需要隔離多個線程之間的共享沖突,可以使用ThreadLocal,這將極大地簡化你的程序,使程序更加易讀、簡潔。

    posted on 2007-09-06 10:54 都市淘沙者 閱讀(169) 評論(0)  編輯  收藏 所屬分類: Java Basic/Lucene/開源資料

    主站蜘蛛池模板: 亚洲a∨无码男人的天堂| a级毛片高清免费视频就| 久久国产亚洲观看| 午夜视频免费观看| 老司机午夜免费视频| 日韩亚洲AV无码一区二区不卡| 成人网站免费观看| 在线免费播放一级毛片| 亚洲毛片在线观看| 亚洲成av人片一区二区三区| 国产免费一区二区三区| 国产精品成人啪精品视频免费| 亚洲人成网站在线观看播放青青| 国产中文在线亚洲精品官网| 成人毛片免费播放| 无码人妻久久一区二区三区免费 | 亚洲国产乱码最新视频| 亚洲国产另类久久久精品| 青青久在线视频免费观看| 波多野结衣免费一区视频| 亚洲精品二三区伊人久久| 亚洲精品乱码久久久久久中文字幕| 亚洲国产精品成人综合久久久 | 久久久久亚洲精品天堂久久久久久 | 国产在线观看免费av站| 美女被爆羞羞网站免费| 国产精品亚洲一区二区无码| 噜噜综合亚洲AV中文无码| 久久亚洲精品无码gv| 亚洲av无码兔费综合| 精品无码专区亚洲| 美女羞羞喷液视频免费| 男男gay做爽爽免费视频| 美国毛片亚洲社区在线观看| 另类图片亚洲校园小说区| 日韩在线一区二区三区免费视频| 曰韩无码AV片免费播放不卡| 香蕉视频免费在线播放| 亚洲阿v天堂在线2017免费| 中文字幕在线免费看线人| 日韩精品无码免费一区二区三区|