JUC包實現的同步機制,原理以及簡單用法總結


      除了用Synchronized關鍵字修飾同步塊,讓線程獲取某對象的鎖實現多線程操作共享變量的同步外,還可以使用java.util.concurrent包。並且,juc包機制下的同步更靈活。juc包的所有鎖都實現自Lock接口和ReadWriteLock接口,下面分別總結。

(圖片來源於網絡)

Lock接口

     Lock在java.util.concurrent.locks包中,Lock是一個接口,我們一般使用的是它的實現類:ReentrantLock (可重入鎖)。ReentrantLock類的主要方法有:

     

void lock() //獲取調用此代碼的對象的鎖,失敗就等待

boolean tryLock() //嘗試獲取調用此代碼的對象的鎖,失敗返回false,不等待

boolean tryLock(long t) //嘗試獲取調用此代碼的對象的鎖,失敗等待 t 時間后返回false

void lockInterruptibly() // 獲取調用此代碼的對象的鎖,失敗就等待。但是這個等待可以中斷 (與syn不同,syn只有wait、join、 sleep的線程可悲中斷)

void unlock() //釋放鎖(必須手動寫明)

 

使用示例如下:

public class Main {
    public static void main(String[] args) {
        Test t = new Test();
        t.readAndWriteSomething(); //main線程要對 t 進行一些需要同步的操作  
}
}
class Test {
    ...
    int value = 1;
    Lock l = new ReentrantLock();

    public void readAndWriteSomething() {
        l.lock();     //獲取 t 的鎖
        .....;   //從 t 讀出寫入一些內容
        l.unlock();  //釋放 t 的鎖
    }
}

大概使用方法就是上面這樣,至於其他的tryLock、lockInterruptibly等方法就看具體情況靈活應用了。但是手動釋放鎖的操作十分重要,不然其他線程可能會飢餓,甚至出現死鎖現象。

ReadWriteLock接口

        我們知道,多個線程讀取並不會造成一些危險。所以我們想,可不可以有一種鎖,在讀操作的時候可以多個線程共享(即鎖可以同時由幾個線程共同持有),寫操作時又變為互斥鎖。ReadWriteLock接口的實現類ReentrantReadWriteLock可以實現這種操作。

ReentrantReadWriteLock中的兩個方法:

Lock readLock()     //返回一個讀鎖,時可以共享的 
Lock writeLock()    //返回一個寫鎖,不可以共享

使用示例:

    

public class Main {
    public static void main(String[] args) {
        Test t = new Test();
        t.readAndWriteSomething(); //main線程要對 t 進行一些需要同步的操作 
}
} class Test { ... int value = 1; Lock l = new ReentrantReadWriteLock(); public void readAndWriteSomething() { l.readLock().lock(); //獲取 t 的讀鎖 .....; //從 t 讀出一些內容 l.readLock().unlock(); //釋放 t 的讀鎖

l.writeLock().lock() //獲取 t 的寫鎖 ...... //從 t 寫入一些內容 l.writeLock().unlock(); //釋放 t 的寫鎖 } }

可以看到,並沒有多復雜,無非把一個對象的鎖拆成讀鎖、寫鎖兩部分而已,其中讀鎖是共享鎖,寫鎖互是斥鎖。讀操作時獲取讀鎖,寫操作時獲取寫鎖。提高效率

 總結二者區別

Synchronized是關鍵字,lock機制是一組類實現;

Synchronized沒有共享鎖,lock機制有讀鎖(共享的);

Synchronized沒有lock靈活,lock可以隨時獲取對象的鎖,但需要手動釋放(這也是靈活的表現);

lock機制下有tryLock返回獲取鎖的結果,成功or失敗;

lock機制下獲取鎖失敗的線程可以被中斷。

當然,lock機制下,每個有同步塊的對象需要持有實現了Lock接口的類的實例,通過這個實例去修改對象的鎖狀態。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM