1. 可重入鎖
ReentrantLock 和 synchronized 都是可重入鎖。
1 class Main{ 2 public synchronized void method1() { 3 method2(); 4 } 5 6 public synchronized void method2() { 7 8 } 9 }
在method1中會調用另外一個synchronized方法method2,此時線程不必重新去申請鎖,而是可以直接執行方法method2。如果不具有可重入性,則會造成死鎖。
2. 可中斷鎖
Lock 是可中斷鎖,而synchronized 不是可中斷鎖。
如果某一線程A正在執行鎖中的代碼,另一線程B正在等待獲取該鎖,可能由於等待時間過長,線程B不想等待了,想先處理其他事情,我們可以讓它中斷自己或者在別的線程中中斷它,這種就是可中斷鎖。
3. 公平鎖
synchronized 是非公平鎖,它無法保證線程獲取鎖的順序。ReentrantLock 與 ReentrantReadWriteLock,它默認情況下是非公平鎖,但是可以設置為公平鎖。
公平鎖即盡量以請求鎖的順序來獲取鎖。比如同時有多個線程在等待一個鎖,當這個鎖被釋放時,等待時間最久(最先請求)的的線程會獲得該鎖,這種就是公平鎖。
1 public ReentrantLock() { 2 sync = new NonfairSync(); 3 } 4 5 public ReentrantLock(boolean fair) { 6 sync = fair ? new FairSync() : new NonfairSync(); 7 }
如果參數為true表示為公平鎖,為fasle為非公平鎖。默認情況下,如果使用無參構造器,則是非公平鎖。
4. 讀寫鎖
讀寫鎖使得多個讀操作不會發生沖突。
如果有一個線程已經占用了讀鎖,則此時其他線程如果要申請寫鎖,則申請寫鎖的線程會一直等待釋放讀鎖。如果有一個線程已經占用了寫鎖,則此時其他線程如果申請寫鎖或者讀鎖,則申請的線程會一直等待釋放寫鎖。
1 public void get(Thread thread) { 2 ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); 3 rwlock.readLock().lock(); 4 try { 5 long start = System.currentTimeMillis(); 6 7 while(System.currentTimeMillis() - start <= 1) { 8 System.out.println(thread.getName()+"正在進行讀操作"); 9 } 10 System.out.println(thread.getName()+"讀操作完畢"); 11 } finally { 12 rwlock.readLock().unlock(); 13 } 14 }