• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見(jiàn)諒!~
            隨筆 - 1469, 文章 - 0, 評(píng)論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            java 線程安全

            四種方式    sychronized關(guān)鍵字

            1. sychronized method(){}
            2. sychronized (objectReference) {/*block*/}
            3. static synchronized method(){}
            4. sychronized(classname.class)

            其中12是代表鎖當(dāng)前對(duì)象,即一個(gè)對(duì)象就一個(gè)鎖34代表鎖這個(gè)類(lèi),即這個(gè)類(lèi)的鎖
            要注意的是sychronized method()不是鎖這個(gè)函數(shù),而是鎖對(duì)象,即:如果這個(gè)類(lèi)中有兩個(gè)方法都是sychronized,那么只要有兩個(gè)線程共享一個(gè)該類(lèi)的reference,每個(gè)調(diào)用這兩個(gè)方法之一,不管是否同一個(gè)方法,都會(huì)用這個(gè)對(duì)象鎖進(jìn)行同步。鎖類(lèi)34類(lèi)推,即該類(lèi)的不同reference調(diào)用了sychronized區(qū)段的咚咚就會(huì)受類(lèi)鎖的控制

            還有,如果兩個(gè)函數(shù)調(diào)用的先后順序不能被打斷,那么可以有個(gè)專門(mén)的鎖對(duì)象來(lái)完成這個(gè)任務(wù):
            class MyLock
            {
                  synchronized getLock()
                  {
                      //####
            還沒(méi)寫(xiě)完
                  }
            }

            五個(gè)等級(jí)   參見(jiàn)effective java  Item 52 Document thread safety

            1. immutable   不可變對(duì)象
            2. thread-safe 線程安全的,可以放心使用,如java.util.Timer
            3. conditionally thread-safe 條件線程安全的,如VectorHashtable,一般是安全的,除非存在幾個(gè)方法調(diào)用之間的順序不能被打斷,這時(shí)可以用額外的鎖來(lái)完成
            4. thread-compatible 可以使用synchronized objectReference)來(lái)協(xié)助完成對(duì)線程的調(diào)用
            5. thread-hostile 不安全的

            wait & notifyAll

            在循環(huán)中使用wait 使用notifyAll而不是notify

            pipe

            java中也有pipe的,四個(gè)類(lèi):PipedInputStream, PipedInputReader, PipedOutputStream, PipedOutputWriter 下面是一段生產(chǎn)者消費(fèi)者的代碼(摘自core javaII):

                /* set up pipes */
                PipedOutputStream pout1 = new PipedOutputStream();
                PipedInputStream pin1 = new PipedInputStream(pout1);
                PipedOutputStream pout2 = new PipedOutputStream();
                PipedInputStream pin2 = new PipedInputStream(pout2);
                /* construct threads */
                Producer prod = new Producer(pout1);
                Filter filt = new Filter(pin1, pout2);
                Consumer cons = new Consumer(pin2);
                /* start threads */
                prod.start(); filt.start(); cons.start();

            注意

            long double是簡(jiǎn)單類(lèi)型中兩個(gè)特殊的咚咚:java讀他們要讀兩次,所以需要同步
            死鎖是一個(gè)經(jīng)典的多線程問(wèn)題,因?yàn)椴煌木€程都在等待那些根本不可能被釋放的鎖,從而導(dǎo)致所有的工作都無(wú)法完成。假設(shè)有兩個(gè)線程,分別代表兩個(gè)饑餓的人,他們必須共享刀叉并輪流吃飯。他們都需要獲得兩個(gè)鎖:共享刀和共享叉的鎖。假如線程 "A" 獲得了刀,而線程 "B" 獲得了叉。線程 A 就會(huì)進(jìn)入阻塞狀態(tài)來(lái)等待獲得叉,而線程 B 則阻塞來(lái)等待 A 所擁有的刀。這只是人為設(shè)計(jì)的例子,但盡管在運(yùn)行時(shí)很難探測(cè)到,這類(lèi)情況卻時(shí)常發(fā)生。雖然要探測(cè)或推敲各種情況是非常困難的,但只要按照下面幾條規(guī)則去設(shè)計(jì)系統(tǒng),就能夠避免死鎖問(wèn)題:

            ·   讓所有的線程按照同樣的順序獲得一組鎖。這種方法消除了 X Y 的擁有者分別等待對(duì)方的資源的問(wèn)題。

            ·    

            ·   將多個(gè)鎖組成一組并放到同一個(gè)鎖下。前面死鎖的例子中,可以創(chuàng)建一個(gè)銀器對(duì)象的鎖。于是在獲得刀或叉之前都必須獲得這個(gè)銀器的鎖。

            ·    

            ·   將那些不會(huì)阻塞的可獲得資源用變量標(biāo)志出來(lái)。當(dāng)某個(gè)線程獲得銀器對(duì)象的鎖時(shí),就可以通過(guò)檢查變量來(lái)判斷是否整個(gè)銀器集合中的對(duì)象鎖都可獲得。如果是,它就可以獲得相關(guān)的鎖,否則,就要釋放掉銀器這個(gè)鎖并稍后再嘗試。

            ·    

            ·   最重要的是,在編寫(xiě)代碼前認(rèn)真仔細(xì)地設(shè)計(jì)整個(gè)系統(tǒng)。多線程是困難的,在開(kāi)始編程之前詳細(xì)設(shè)計(jì)系統(tǒng)能夠幫助你避免難以發(fā)現(xiàn)死鎖的問(wèn)題。

            Volatile 變量. volatile 關(guān)鍵字是 Java 語(yǔ)言為優(yōu)化編譯器設(shè)計(jì)的。以下面的代碼為例:

            class VolatileTest {

             

               public void foo() {

                  boolean flag = false;

             

                  if(flag) {

                     //this could happen

                  }

               }

            }

             

            一個(gè)優(yōu)化的編譯器可能會(huì)判斷出 if 部分的語(yǔ)句永遠(yuǎn)不會(huì)被執(zhí)行,就根本不會(huì)編譯這部分的代碼。如果這個(gè)類(lèi)被多線程訪問(wèn), flag 被前面某個(gè)線程設(shè)置之后,在它被 if 語(yǔ)句測(cè)試之前,可以被其他線程重新設(shè)置。用 volatile 關(guān)鍵字來(lái)聲明變量,就可以告訴編譯器在編譯的時(shí)候,不需要通過(guò)預(yù)測(cè)變量值來(lái)優(yōu)化這部分的代碼。

             

            無(wú)法訪問(wèn)的線程 有時(shí)候雖然獲取對(duì)象鎖沒(méi)有問(wèn)題,線程依然有可能進(jìn)入阻塞狀態(tài)。在 Java 編程中 IO 就是這類(lèi)問(wèn)題最好的例子。當(dāng)線程因?yàn)閷?duì)象內(nèi)的 IO 調(diào)用而阻塞時(shí),此對(duì)象應(yīng)當(dāng)仍能被其他線程訪問(wèn)。該對(duì)象通常有責(zé)任取消這個(gè)阻塞的 IO 操作。造成阻塞調(diào)用的線程常常會(huì)令同步任務(wù)失敗。如果該對(duì)象的其他方法也是同步的,當(dāng)線程被阻塞時(shí),此對(duì)象也就相當(dāng)于被冷凍住了。其他的線程由于不能獲得對(duì)象的鎖,就不能給此對(duì)象發(fā)消息(例如,取消 IO 操作)。必須確保不在同步代碼中包含那些阻塞調(diào)用,或確認(rèn)在一個(gè)用同步阻塞代碼的對(duì)象中存在非同步方法。盡管這種方法需要花費(fèi)一些注意力來(lái)保證結(jié)果代碼安全運(yùn)行,但它允許在擁有對(duì)象的線程發(fā)生阻塞后,該對(duì)象仍能夠響應(yīng)其他線程。

            調(diào)用
            yield() 方法能夠?qū)?dāng)前的線程從處理器中移出到準(zhǔn)備就緒隊(duì)列中。另一個(gè)方法則是調(diào)用 sleep() 方法,使線程放棄處理器,并且在 sleep 方法中指定的時(shí)間間隔內(nèi)睡眠。

            正如你所想的那樣,將這些方法隨意放在代碼的某個(gè)地方,并不能夠保證正常工作。如果線程正擁有一個(gè)鎖(因?yàn)樗谝粋€(gè)同步方法或代碼塊中),則當(dāng)它調(diào)用 yield() 時(shí)不能夠釋放這個(gè)鎖。這就意味著即使這個(gè)線程已經(jīng)被掛起,等待這個(gè)鎖釋放的其他線程依然不能繼續(xù)運(yùn)行。為了緩解這個(gè)問(wèn)題,最好不在同步方法中調(diào)用 yield 方法。將那些需要同步的代碼包在一個(gè)同步塊中,里面不含有非同步的方法,并且在這些同步代碼塊之外才調(diào)用 yield

            另外一個(gè)解決方法則是調(diào)用 wait() 方法,使處理器放棄它當(dāng)前擁有的對(duì)象的鎖。如果對(duì)象在方法級(jí)別上使同步的,這種方法能夠很好的工作。因?yàn)樗鼉H僅使用了一個(gè)鎖。如果它使用 fine-grained 鎖,則 wait() 將無(wú)法放棄這些鎖。此外,一個(gè)因?yàn)檎{(diào)用 wait() 方法而阻塞的線程,只有當(dāng)其他線程調(diào)用 notifyAll() 時(shí)才會(huì)被喚醒。

            在進(jìn)行多線程編程時(shí),經(jīng)常要使用同步互斥機(jī)構(gòu),但java本身沒(méi)有提供的同步互斥機(jī)構(gòu),僅提供了兩個(gè)與同步互斥有關(guān)的方法:wait()notify(),可以用來(lái)設(shè)計(jì)信號(hào)量類(lèi):mySemaphore,它是按照Dijkstra提出的計(jì)數(shù)信號(hào)量的思想設(shè)計(jì)的。

            mySemaphore
            有兩個(gè)最重要的成員方法:P()V()。這兩個(gè)方法實(shí)際就實(shí)現(xiàn)了信號(hào)量的P操作和V操作。具體描述如下:

            public synchronized void P(){

            semaphore--;

            if(semaphore<0){

            try{

            wait();

            }catch(InterruptedException ie){}

            }

            }

            public synchronized void V(){

            semaphore++;

            if(semaphore<=0)

            notify();

            }

            其中,semaphore變量記錄了信號(hào)量的狀態(tài),wait()方法相當(dāng)于block原語(yǔ),用于阻塞線程的執(zhí)行,notify()方法相當(dāng)于wakeup原語(yǔ),用于喚醒線程恢復(fù)運(yùn)行。由于這兩個(gè)方法定義為synchronized,這樣java虛擬機(jī)可保證這兩個(gè)方法的原子執(zhí)行,從而實(shí)現(xiàn)了PV操作。

            二、管道

            并發(fā)程序的多個(gè)線程之間的通訊通常是使用管道進(jìn)行,jdk提供了兩個(gè)管道類(lèi):PipedInpuStreamPipedOutputStream,前者用于輸入,后者用于輸出。這兩種管道應(yīng)該是能夠多次連接和關(guān)閉,在實(shí)現(xiàn)過(guò)程中,卻發(fā)現(xiàn)它們?cè)陉P(guān)閉后,不能重新建立連接。經(jīng)過(guò)仔細(xì)調(diào)試后,發(fā)現(xiàn)jdk的源代碼在處理關(guān)閉時(shí)釋放資源存在著缺陷,因此需要編寫(xiě)自己的管道類(lèi):MyPipedInputStreamMyPipedOutputStream。這兩個(gè)類(lèi)直接從InputStreamOutputStream繼承而來(lái),其成員方法與實(shí)現(xiàn)基本與PipedInputStreamPipedOutputStream一致,只是在處理關(guān)閉時(shí),將類(lèi)中的成員變量的值恢復(fù)成未連接時(shí)的初始值。另外,原有的管道了提供的管道容量只有1024個(gè)字節(jié),在傳輸數(shù)據(jù)量較大時(shí),可能會(huì)發(fā)生溢出,而在自己的管道類(lèi)中可以任意設(shè)置管道容量,例如可以根據(jù)需要把管道容量設(shè)為64KB。以下僅給出了相應(yīng)的關(guān)閉例程:

            1
            MyPipedInputStream

            public void close() throws IOException {

            in = -1;

            out = 0;

            closedByReader = true;

            connected = false;

            closed = true;

            buffer = new byte[PIPE_SIZE];

            }

            2
            MyPipedOutputStream

            public void close() throws IOException {

            if (sink != null) {

            sink.receivedLast();

            sink.closed = true;

            }

            sink = null;

            connected = false;

            }

             

            posted on 2009-08-25 22:44 肥仔 閱讀(368) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): Web-后臺(tái)

            综合网日日天干夜夜久久| 久久精品夜夜夜夜夜久久| 久久久WWW免费人成精品| yellow中文字幕久久网| 亚洲国产精品综合久久一线 | 一级a性色生活片久久无少妇一级婬片免费放 | 成人精品一区二区久久| 欧美一级久久久久久久大片| 伊人久久大香线蕉综合Av| 久久成人18免费网站| 久久精品国产亚洲AV大全| 久久www免费人成看国产片| 无码伊人66久久大杳蕉网站谷歌| 亚洲欧美日韩精品久久| 国产亚洲精品久久久久秋霞| 久久国产精品偷99| 久久综合噜噜激激的五月天| 久久影院午夜理论片无码 | 久久99亚洲综合精品首页| 亚洲色婷婷综合久久| 久久影院亚洲一区| 99久久精品费精品国产| 久久久噜噜噜久久中文福利| 亚洲精品国产自在久久| 精品久久综合1区2区3区激情| 色综合久久综合中文综合网| 色婷婷久久久SWAG精品| 久久久网中文字幕| 热久久国产精品| 日本一区精品久久久久影院| 激情伊人五月天久久综合| 亚洲精品无码专区久久久| 久久天天婷婷五月俺也去 | 久久精品中文騷妇女内射| 久久久无码精品亚洲日韩蜜臀浪潮| 久久综合狠狠综合久久激情 | 精品久久久久久亚洲精品| 伊人久久大香线蕉综合Av| 亚洲中文字幕无码久久2017| 久久人妻无码中文字幕| 亚洲综合精品香蕉久久网|