亚洲免费乱码视频,日韩 欧美 国产 动漫 一区,97在线观看免费视频播国产,中文字幕亚洲图片

      1. <legend id="ppnor"></legend>

      2. 
        
        <sup id="ppnor"><input id="ppnor"></input></sup>
        <s id="ppnor"></s>

        Java進(jìn)階:Java多線程之ThreadLocal

        字號(hào):

        ThreadLocal的核心思想很簡(jiǎn)單:為每個(gè)獨(dú)立的線程提供一個(gè)變量的副本。
            Java提供的synchronized關(guān)鍵字使用了“同步鎖”的機(jī)制來(lái)阻止線程的競(jìng)爭(zhēng)訪問,即“以時(shí)間換空間”。: " 10pt; FONT-SIZE:>  ThreadLocal則使用了“拷貝副本”的方式,人人有份,你用你的,我用我的,大家互不影響,是“以空間換時(shí)間”。每個(gè)線程修改變量時(shí),實(shí)際上修改的是變量的副本,不怕影響到其它線程。
            為了加深對(duì)ThreadLocal的理解,下面我使用一個(gè)例子來(lái)演示ThreadLocal如何隔離線程間的變量訪問和修改:
            【1】SerialNum類
            packageexample.thread.threadLocal;
            publicclassSerialNum{
            privatestaticintnextSerialNum=1;
            @SuppressWarnings("unchecked")
            privatestaticThreadLocalserialNum=newThreadLocal(){
            protectedsynchronizedObjectinitialValue(){
            returnnewInteger(nextSerialNum++);
            }
            };
            publicstaticintget(){
            return((Integer)(serialNum.get())).intValue();
            }
            @SuppressWarnings("unchecked")
            publicstaticvoidset(IntegernewSerial){
            serialNum.set(newSerial);
            }
            }
            【2】GetSerialNumThread
            packageexample.thread.threadLocal;
            publicclassGetSerialNumThreadimplementsRunnable{
            publicstaticvoidmain(Stringargs[]){
            GetSerialNumThreadserialNumGetter=newGetSerialNumThread();
            Threadt1=newThread(serialNumGetter,"ThreadA");
            Threadt2=newThread(serialNumGetter,"ThreadB");
            t1.start();
            try{
            t1.join();
            }catch(InterruptedExceptione){
            e.printStackTrace();
            }  t2.start();
            }
            publicvoidrun(){
            intmySerialNum=getSerialNum();
            System.out.println("線程"+Thread.currentThread().getName()
            +"獲取到的序列號(hào)是"+mySerialNum);
            System.out.println("線程"+Thread.currentThread().getName()
            +"修改了序列號(hào)為"+(mySerialNum*3));
            setSerialNum(mySerialNum*3);
            System.out.println("線程"+Thread.currentThread().getName()
            +"再次獲得的序列號(hào)是"+getSerialNum());
            }
            privateintgetSerialNum(){
            returnSerialNum.get();
            }
            privatevoidsetSerialNum(intnewSerialNum){
            SerialNum.set(newInteger(newSerialNum));
            }
            }  運(yùn)行的結(jié)果如下:
            線程 Thread A 獲取到的序列號(hào)是1
            線程 Thread A 修改了序列號(hào)為3
            線程 Thread A 再次獲得的序列號(hào)是3
            線程 Thread B 獲取到的序列號(hào)是2
            線程 Thread B 修改了序列號(hào)為6
            線程 Thread B 再次獲得的序列號(hào)是6
            可見第一個(gè)線程在調(diào)用SerialNum.set(int)方法修改static變量時(shí),其實(shí)修改的是它自己的副本,而不是修改本地變量,第二個(gè)線程在初始化的時(shí)候拿到的序列號(hào)是2而不是7。
            為什么會(huì)這樣呢?明明serialNum是靜態(tài)變量???其實(shí)我們只需要看看ThreadLocal的內(nèi)部構(gòu)造就知道了:
            A. ThreadLocal的get()方法:
            /**
            *Returnsthevalueinthecurrentthread’scopyofthisthread-local
            *variable. Createsandinitializesthecopyifthisisthefirsttime
            *thethreadhascalledthismethod.
            *
            *@returnthecurrentthread’svalueofthisthread-local
            */
            publicTget(){
            Threadt=Thread.currentThread();
            ThreadLocalMapmap=getMap(t);
            if(map!=null)
            return(T)map.get(this);
            //Mapsareconstructedlazily. ifthemapforthisthread
            //doesn’texist,createit,withthisThreadLocalandits
            //initialvalueasitsonlyentry.
            Tvalue=initialValue();
            createMap(t,value);
            returnvalue;
            }
            B. ThreadLocal的set()方法:
            /**
            *Setsthecurrentthread’scopyofthisthread-localvariable
            *tothespecifiedvalue. Manyapplicationswillhavenoneedfor
            *thisfunctionality,relyingsolelyonthe{@link#initialValue}
            *methodtosetthevaluesofthread-locals.
            *
            *@paramvaluethevaluetobestoredinthecurrentthreads’copyof
            *  thisthread-local.
            */
            publicvoidset(Tvalue){
            Threadt=Thread.currentThread();
            ThreadLocalMapmap=getMap(t);
            if(map!=null)
            map.set(this,value);
            else
            createMap(t,value);
            }
            可以看到ThreadLocal在內(nèi)部維護(hù)了一個(gè)Map,將變量的值和線程綁定起來(lái),get/set方法都是對(duì)該線程對(duì)應(yīng)的value進(jìn)行操作,所以不會(huì)影響到其它線程。