多線程同步的實現方式

Java主要提供了3種實現多線程同步的機制:

(1)synchronized關鍵字

在Java語言中,每個對象都有一個對象鎖與之相關聯,該鎖表明對象在任何時候只允許被一個線程所擁有,每當一個線程調用對象的一段synchronized代碼時需要先獲取這個鎖,然後再執行相應的代碼,執行結束後釋放鎖。

synchronized關鍵字主要有兩種用法(synchronized塊和synchronized方法),此外該關鍵字還可以作用於靜態方法、類或某個實例。

(a)synchronized方法。在方法的聲明前加入synchronized關鍵字,示例如下:

public synchronized void Test();

只要把多個線程對類需要被同步的資源放到Test()方法中,就能保證這個方法在同一時間只能被一個線程訪問,從而保證了多線程訪問的安全性。然而,當一個方法的方法體規模非常大時,該方法聲明爲synchronized會大大降低程序執行效率。爲此,Java提供了synchronized塊。

(b)synchronized塊。synchronized塊既可以把任意代碼聲明爲synchronized,也可以指定上鎖的對象,非常靈活。用法如下:

synchronized (synObject){
     //訪問synObject的代碼
 }

(2)wait()方法和notify()方法

當使用synchronized修飾某個共享資源時,如果線程1在執行synchronized代碼,線程2也要執行同一對象的同一synchronized代碼時,線程2要等線程1執行完成後才能繼續執行。這種情況下可以使用wait()方法和notify()方法。

在synchronized代碼被執行期間,線程可以調用對象的wait()方法,釋放對象鎖,進入等待狀態,並且可以調用notify()方法或notifyAll()方法通知正在等待的其他線程。notify()方法僅喚醒一個線程(等待隊列中的第一個線程)並允許它去獲得鎖,notifyAll()方法喚醒所有等待這個對象的線程並允許他們去獲得鎖(它們通過競爭的方式獲得資源)

(3)Lock

JDK5新增加了Lock接口以及他的一個實現類ReentrantLock(重入鎖),Lock也可以用來實現多線程的同步,方法如下:

(a)lock()。以阻塞的方式獲得鎖,即如果得到了鎖立即返回;否則等待,知道獲得鎖返回。

(b)tryLock()。以非阻塞的方式獲得鎖,即如果得到立即返回true,否則立即返回false。

(c)tryLock(long timeout,TimeUnit unit)。如果獲得鎖,立即返回true,否則等待參數給定的時間單元,在等待過程中如果獲得鎖返回true,如果等待超時返回false。

(d)lockInterruptibly()。如果獲得鎖,立即返回,如果沒有,當前線程處於休眠狀態,直到獲得鎖,或者當前線程被別的線程中斷(會受到InterruptedException異常)。與lock()的區別是,如果lock()方法獲取不到鎖,會一直處於阻塞,且會忽略Interrupt()方法。

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