posts - 60,comments - 71,trackbacks - 0

          什么是ThreadLocal

          ThreadLocal并不能從字面上理解為線程的本地實(shí)現(xiàn)版本,因?yàn)樗⒉皇且粋€(gè)線程,而是ThreadLocal Variable(線程局部變量)。它的功能非常簡(jiǎn)單,就是為每一個(gè)使用該變量的線程都提供一個(gè)變量值的副本,使得每一個(gè)線程都可以獨(dú)立地改變自己的副本,而不會(huì)和其他線程珠副本沖突。從線程的角度看,就好像每一個(gè)線程都完全擁有該變量。
          首先看看ThreadLocal的方法:
          1、get()
            返回當(dāng)前線程的線程局部變量的副本,當(dāng)?shù)谝淮握{(diào)用這個(gè)方法時(shí)會(huì)自動(dòng)創(chuàng)建并且初始化一個(gè)線程局部變量的副本。
          2、initialValue()
            返回該線程的線程局部變量的當(dāng)前線程的初始值,這個(gè)方法只在第一次調(diào)用get()方法的時(shí)候被調(diào)用一次。如果在調(diào)用get()方法之前已經(jīng)調(diào)用了set()方法,那么這個(gè)方法將不會(huì)被調(diào)用。
          這個(gè)方法是一個(gè)protected的方法,不能直接調(diào)用該方法,只有在其子類中將該方法重寫(xiě)才能改變它的行為。在默認(rèn)情況下,該方法的返回值為null。
          3、set()
            設(shè)置當(dāng)前線程的線程局部變量副本的值。大多數(shù)的應(yīng)用程序都不需要調(diào)用這個(gè)方法,可以通過(guò)initialValue()方法來(lái)設(shè)置當(dāng)前線程局部變量的值。
          4、remove()
            移除當(dāng)前線程局部變量的值。這樣做的目的是可以降低當(dāng)前線程的存儲(chǔ)空間的使用量,這是Java1.5的新增方法。

          ThreadLocal的使用
          ThreadLocal的使用方法有兩種,一種方法是自己實(shí)現(xiàn)ThreadLocal的子類,并重寫(xiě)initialValue()方法。另一種方法是定義一個(gè)表態(tài)的ThreadLocal實(shí)例,通過(guò)使用set()方法來(lái)初始化這個(gè)線程局部變量的值。
            如果希望線程局部變量初始化的時(shí)候就具有值,那么需要自己實(shí)現(xiàn)ThreadLocal的子類并重寫(xiě)該方法,通常使用一個(gè)內(nèi)部匿名類對(duì)ThreadLocal進(jìn)行子類化。例如在下面的例子中,SerialNum類為每一個(gè)類分配一個(gè)序號(hào):
          程序代碼 程序代碼
          public class SerialNum
          {
           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();
           }
          }

          同樣,也可以不采用實(shí)現(xiàn)ThreadLocal子類的方法來(lái)實(shí)現(xiàn)同樣的功能,如下所示:
          程序代碼 程序代碼
          public class SerialNum1
          {
           private static int nextSerialNum=0;
           private static ThreadLocal serialNum=new ThreadLocal();
           public static int get()
           {
            if(serialNum.get()==null)
             serialNum.set(new Integer(nextSerialNum++));
            return ((Integer)(serialNum.get())).intValue();
           }

          }

            SerialNum類的使用非常簡(jiǎn)單,因?yàn)間et()方法是static的,所以在需要獲取當(dāng)前線程的序號(hào)時(shí),簡(jiǎn)單地調(diào)用int serial=SerialNum.get();即可。
            在線程是活動(dòng)并且ThreadLocal對(duì)象是可訪問(wèn)時(shí),該線程就持有一個(gè)到該線程局部變量副本的隱含引用。當(dāng)該線程運(yùn)行結(jié)束后,該線程擁有的所有線程局部變量的副本都將失效,并等待垃圾收集器收集。

            ThreadLocal 幾點(diǎn)作用:
          1)可以啟到類似單態(tài)類的作用,實(shí)際上是要使某變量達(dá)到線程安全時(shí),可以使用這種方式;
          2)可以結(jié)合HttpServletRequest,HttpServletResponse,ServletContext等來(lái)實(shí)現(xiàn)使用運(yùn)行時(shí)數(shù)據(jù);

          在使用ThreadLocal 時(shí)一般是使用get()方法,但在使用這個(gè)方法時(shí),會(huì)先調(diào)用set()方法,具體的用途可以在創(chuàng)建ThreadLocal 變量時(shí)指定,也可以

          重寫(xiě)set()方法,如果不想設(shè)定set()方法,可以在創(chuàng)建ThreadLocal 變量時(shí)指定,如下:

          private static ThreadLocal currentUser = new ThreadLocal(){
                   
          protected synchronized Object initialValue() {
                           
          return new User();
                   }

               }
          ;

          或者使用:public static void setCurrentUser(User user) { currentUser.set(user); }手工給ThreadLocal 變量賦值(user),
          要獲得User對(duì)象時(shí),可以使用 User u = (User)currentUser.get();即直接調(diào)用get()方法,來(lái)返回set()方法所設(shè)置的值(也可以不寫(xiě)
          此方法,而直接在定義變量時(shí),重寫(xiě)initialValue()方法,此方法返回所要設(shè)置的值或?qū)ο?,這里是User對(duì)象,然后調(diào)用User類的其他方法.


           
          posted on 2008-05-04 20:37 henry1451 閱讀(1341) 評(píng)論(0)  編輯  收藏 所屬分類: Java技術(shù)
          主站蜘蛛池模板: 葵青区| 孟州市| 土默特左旗| 岳西县| 天祝| 化州市| 永靖县| 普兰店市| 鄂州市| 龙川县| 公安县| 陇川县| 红原县| 萨嘎县| 始兴县| 信阳市| 龙海市| 石城县| 当雄县| 永兴县| 治县。| 安新县| 贵德县| 井冈山市| 贡山| 沅江市| 黄骅市| 高青县| 习水县| 通榆县| 易门县| 葫芦岛市| 新兴县| 错那县| 新沂市| 安徽省| 株洲市| 滁州市| 铜陵市| 扎鲁特旗| 福州市|