1. 程式人生 > >java的鎖機制,synchronize與Lock比較

java的鎖機制,synchronize與Lock比較

以前執行緒同步只知道synchronize關鍵字,後來才知道還有個lock,為什麼還要有個lock來實現同步呢

synchronized的侷限性

  • 佔有鎖的執行緒等待IO或者其他原因被阻塞,沒有釋放鎖的情況下,其他執行緒一直阻塞
  • 多個執行緒同時讀寫檔案的時候,讀和讀操作也會發生衝突
  • 我們沒有辦法知道當前我們的執行緒是否成功獲取了鎖,只能傻傻的等待

有這些限制所有其他的同步機制來解決,所以就有了lock,lock常用的兩個介面和兩個實現
第一個,Lock介面,我們來看下它的定義

package java.util.concurrent.locks;
import java.util.concurrent.TimeUnit;

public
interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long time, TimeUnit unit) throws InterruptedException; void unlock(); Condition newCondition(); }

這幾個方法的作用分別是

  • lock()獲取鎖,沒有獲取一直等待,無返回值
  • lockInterruptibly()獲取鎖一直等待,無返回值,但是可以被thread.interrupt()方法中斷,丟擲異常
  • tryLock()獲取鎖,不等待,返回是否獲取成功
  • tryLock(long time, TimeUnit unit)獲取鎖,沒有獲取等待指定時間,返回是否獲取成功,等待時候可以被thread.interrupt()方法中斷,丟擲異常
  • unlock()釋放鎖
  • newCondition()實現執行緒間的互動,與Object的wait,notify,notify對應
    生產者消費者兩種實現方式

synchronize與lock的鎖的釋放

  • synchronize滿足下列三個條件之一釋放鎖
    • 佔有鎖的執行緒執行完畢
    • 佔有鎖的執行緒異常退出
    • 佔有鎖的執行緒進入waiting狀態釋放鎖
  • Lock必須呼叫unlock()方法
    Lock介面的唯一實現ReentrantLock,意思是可重入鎖,可重入鎖後面介紹

第二個,ReadWriteLock介面,我們來看下它的定義

package java.util.concurrent.locks;

public interface ReadWriteLock {
    /**
     * Returns the lock used for reading.
     *
     * @return the lock used for reading
     */
    Lock readLock();

    /**
     * Returns the lock used for writing.
     *
     * @return the lock used for writing
     */
    Lock writeLock();
}

註釋寫的很清楚,為了解決兩個執行緒同時讀操作還互斥的問題
ReentrantReadWriteLock()為ReadWriteLock 介面的實現

一些鎖的概念

  • 可重入鎖,同一個執行緒呼叫同鎖的多個程式碼塊和方法不會重複加鎖,sy和Lock和readwritelock都是可重入鎖
  • 可中斷鎖 在等待的過程中可中斷,lockInterruptibly()獲取的就是可中斷鎖,中斷會丟擲異常
  • 公平鎖,上面介紹的兩個鎖都可以加入Boolean型的構造引數,預設是非公平鎖,多個執行緒同時等待,當前執行緒執行完畢,隨機執行下個執行緒,公平鎖即先到先執行
  • 讀寫鎖,讀寫鎖,即讀鎖和寫鎖是分開的