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

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

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

    隨筆-14  評論-142  文章-0  trackbacks-0


    ThreadLocal的設(shè)計與使用






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

      ThreadLocal是什么

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

      ThreadLocal的設(shè)計

      首先看看ThreadLocal的接口:

      Object get() ; // 返回當(dāng)前線程的線程局部變量副本 protected Object initialValue(); // 返回該線程局部變量的當(dāng)前線程的初始值void set(Object value); // 設(shè)置當(dāng)前線程的線程局部變量副本的值

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





    protected Object initialValue() { return null; }

      ThreadLocal是如何做到為每一個線程維護(hù)變量的副本的呢?其實實現(xiàn)的思路很簡單,在ThreadLocal類中有一個Map,用于存儲每一個線程的變量的副本。比如下面的示例實現(xiàn):





    public class ThreadLocal
    {
     private Map values = Collections.synchronizedMap(new HashMap());
     public Object get()
     {
      Thread curThread = Thread.currentThread();
      Object o = values.get(curThread);
      if (o == null && !values.containsKey(curThread))
      {
       o = initialValue();
       values.put(curThread, o);
      }
      return o;
     }

     public void set(Object newValue)
     {
      values.put(Thread.currentThread(), newValue);
     }

     public Object initialValue()
     {
      return null;
     }
    }

      當(dāng)然,這并不是一個工業(yè)強(qiáng)度的實現(xiàn),但JDK中的ThreadLocal的實現(xiàn)總體思路也類似于此。

      ThreadLocal的使用

      如果希望線程局部變量初始化其它值,那么需要自己實現(xiàn)ThreadLocal的子類并重寫該方法,通常使用一個內(nèi)部匿名類對ThreadLocal進(jìn)行子類化,比如下面的例子,SerialNum類為每一個類分配一個序號:





    public class SerialNum
    {
     // The next serial number to be assigned

     private static int nextSerialNum = 0;
     private static ThreadLocal serialNum = new ThreadLocal()
     {
      protected synchronized Object initialValue()
      {
       return new Integer(nextSerialNum++);
      }
     };

     public static int get()
     {
      return ((Integer) (serialNum.get())).intValue();
     }
    }

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





    int serial = SerialNum.get();

      即可。

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

      ThreadLocal與其它同步機(jī)制的比較

      ThreadLocal和其它同步機(jī)制相比有什么優(yōu)勢呢?ThreadLocal和其它所有的同步機(jī)制都是為了解決多線程中的對同一變量


    posted on 2006-10-04 06:47 liulang 閱讀(598) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: a毛片在线免费观看| 亚洲人av高清无码| 国产一级片免费看| 亚洲AV无码久久精品色欲| 在线免费观看h片| 亚洲AV永久无码精品水牛影视 | 国产精品亚洲综合网站| 免费人成大片在线观看播放电影| 午夜视频免费观看| 国产免费午夜a无码v视频| 亚洲日韩AV一区二区三区中文| 午夜宅男在线永久免费观看网| 国产一区二区三区免费在线观看| 亚洲第一成年免费网站| 免费观看国产小粉嫩喷水| 日本黄页网址在线看免费不卡| 久久久精品国产亚洲成人满18免费网站 | 成人精品国产亚洲欧洲| 久久久久久影院久久久久免费精品国产小说 | 亚洲Av无码一区二区二三区| 九九九国产精品成人免费视频| 麻豆国产精品免费视频| 激情综合亚洲色婷婷五月APP| 免费看大黄高清网站视频在线| 老司机精品视频免费| 亚洲精品无码专区在线在线播放| 日韩在线视精品在亚洲| 久久亚洲国产精品五月天婷| 久久国产精品萌白酱免费| 精品国产亚洲男女在线线电影| 成人无码a级毛片免费| 亚洲综合免费视频| 国产又粗又长又硬免费视频 | 中文字幕在线观看亚洲视频| 国产精品va无码免费麻豆| 中国一级特黄的片子免费 | 亚洲国产日韩a在线播放| 国产L精品国产亚洲区久久| 亚洲国产成人精品无码区二本| 亚洲人成电影网站国产精品| 亚洲avav天堂av在线网毛片|