多線程(線程安全、線程間通信、1.5中的Lock)總結2


判斷線程中是否有安全隱患?

       1,先明確線程的代碼有哪些

       2,線程代碼中是否有共享數據

       3,是否有多條語句操作共享數據

解決方法:

       同步解決

同步函數:synchronized 作爲修飾詞加在函數上。

       持的鎖是:this

同步函數和同步代碼塊的區別?

       同步函數比同步代碼塊簡單。

       同步函數不用刻意定義鎖對象,減少了代碼的縮進

       同步函數用的鎖是固定的:就是this。

       同步代碼塊鎖是任意的。

       相對而言,同步代碼塊用的多一些。而且鎖是指定的,閱讀性好一些。

靜態同步函數的鎖是什麼呢?

       該類的所屬字節碼文件對象:類名.Class

類名.class :是一個屬性,表示該類所屬的字節碼文件對象。

 

懶漢式被多線程併發訪問時:

       會出現線程安全問題,因爲:

              1,多個線程共享一個對象。

              2,有多條語句操作共享數據。

懶漢式中減少鎖的判斷次數:

       多一層判段。

面試:懶漢式,併發訪問?,提高效率?。

class SingleDemo{

       private static  SingleDemo sg;

       private SingleDemo(){}

       public static SingleDemo getInstance(){

              if(sg!=null){

                     synchronized(SingleDemo.class) {

                           

                            if(sg!=null){

                                   sg = newSingleDemo();

                            }

                     }

              }

              return sg;

       }

}

線程間通信:

多個線程處理同一個資源,但是處理的動作卻一樣。

常用的機制是等待喚醒機制。


wait():將運行的線程置於凍結狀態,釋放了執行權和執行資格,並將等待的線程存儲

到了線程池。

notify():

       對線程池中的等待線程進行喚醒,讓線程恢復到運行狀態,

       或者恢復到臨時阻塞狀態。其實就是讓等待的線程再次具備執行資格。

       注意:一次只喚醒一個,而且隨機的。

notifyAll():

       喚醒線程池中所有的等待線程。

wait notifynotifyAll方法都用在同步中。

必須標示出是作用在哪個同步的鎖上。

用法:鎖.wait 鎖.notify 鎖.notifyAll();


java.util.concurrent.locks

Lock接口

在jdk1.5中提供了Lock對象。

lock();獲取鎖

unlock();釋放鎖

newCondition():獲取與鎖相結合的Condition對象。

 

Condition:

       await

       signal

       signalAll

 

在jdk1.5中提供了Lock對象替代了synchronized

Lock接口中提供了獲取鎖lock(),釋放鎖unlock();

 

同步使用的隱士的獲取鎖和釋放鎖動作。

而升級後,將獲取鎖和釋放鎖變成顯示的。

 

以前同步中用於操作鎖的方法 wait notify notifyAll,

也被jdk1.5中的對象替代了,替代對象是Condition,將操作的鎖的方法單獨從Object中封裝到了Condition對象中。

 

早期同步中的鎖用的Object中的操作方waitnotify notifyAll。

 

升級後。

同步鎖被Lock替代變成了指定鎖。Object中方法也被Condition封裝替代,替代方法是Condition對象的中awaitsignal signalAll。

那麼升級後,在對鎖操作,就必須讓Lock和Condition相結合.

 

如何將Lock和Condition結合呢?

 

可以通過Lock接口中的newCondition()來獲取和該鎖對象相結合的Condition操作的鎖的方法

 

新升級的內容Lock Condition的好處:

一個Lock可以綁定多個 用於操作鎖的方法對象。 Lock上可以有多個Condition。這樣就解決了

多生產者和多消費者以前用notifyAll喚醒全部,導致本方被喚醒效率低的問題。

 

給生產者分配一個Condition,給消費者分配另一個Condition。

可以實現,生產者中喚醒消費者,而不在喚醒本方

停止線程:

       如何停止:結束run方法,即結束循環,結束循環一般是判斷或修改標記。

當線程中存在凍結線程的語句時,讀不到修改標記的語句。需要用到interrupt來強制中斷線程的凍結狀態。

interrupt:

強制中斷線程的凍結狀態,讓線程變成運行或臨時阻塞狀態。不拋出interruptedExceptio異常。

setDaemon(Boolean):

       將線程設置爲守護線程,需要在開啓線程之前設置;

       守護線程可以簡單理解爲後臺線程;

當前臺線程都結束時,後臺線程自動結束;

當線程都變成守護線程時,進程結束。

join:

       當執行線程(A)執行到某一個線程(B)時,該線程(A)會釋放執行權和執行資格處於凍結狀態。

       此時某一個線程(B)會被執行,而執行線程(A)必須等到某一個線程(B)執行完畢後,該執行線程纔可以被執行。

       何時用join方法:

       當在執行過程中,需要臨時加入一個線程進行運算,可以使用join方法。

toString:

       Thread.currentThread().toString()

       返回當前線程的名字、優先級、所屬的線程組。

setPrivority:

       設置線程優先級。1—10;數值越大優先級越高。

       MAX_PRIORITY          10

       MIN_PRIORITY      1

       NORM_PRIORITY          5

yield():

       暫停當前線程並執行其他線程。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章