Lock鎖的簡單使用方法


 

ReentrantLock

1.什么是ReentrantLock

1.1ReentrantLock 與Synchronized區別

在面試中詢問ReentrantLock與Synchronized區別時,一般回答都是

ReentrantLock

  • ReentrantLock是JDK方法,需要手動聲明上鎖和釋放鎖,因此語法相對復雜些;如果忘記釋放鎖容易導致死鎖
  • ReentrantLock具有更好的細粒度,可以在ReentrantLock里面設置內部Condititon類,可以實現分組喚醒需要喚醒的線程
  • RenentrantLock能實現公平鎖

Synchronized

  • Synchoronized語法上簡潔方便
  • Synchoronized是JVM方法,由編輯器保證枷鎖和釋放

 構造方法

public class ReentrantLock implements Lock, java.io.Serializable {

 public ReentrantLock() {
        sync = new NonfairSync();
    }

    /**
     * Creates an instance of {@code ReentrantLock} with the
     * given fairness policy.
     *
     * @param fair {@code true} if this lock should use a fair ordering policy
     */
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

}

ReentrantLock有兩個構造方法,一個是無參的 ReentrantLock() ;另一個含有布爾參數public ReentrantLock(boolean fair)。后面一個構造函數說明ReentrantLock可以新建公平鎖;而Synchronized只能建立非公平鎖

(公平鎖:公平鎖,是按照通過CLH等待線程按照先來先得的規則,公平的獲取鎖;而非公平鎖,則當線程要獲取鎖時,它會無視CLH等待隊列而直接獲取鎖

轉裝於:https://www.cnblogs.com/kexianting/p/8550975.html

Lock中的newCondition方法

 public Condition newCondition() {
        return sync.newCondition();
    }

Condition詳解:https://www.cnblogs.com/gemine/p/9039012.html 與Object的wait與notify用法類似。

獲取鎖的方式

void lock()獲取鎖。

void lockInterruptibly()如果當前線程未被中斷,則獲取鎖。

boolean tryLock() 僅在調用時鎖未被另一個線程保持的情況下,才獲取該鎖。

boolean tryLock(long timeout, TimeUnit unit) timeout:時間long值如10L   TimeUnit 時間單位如TimeUnit.SECONDS 代表等待10秒若未獲取到鎖則放棄。

public class MyLock implements Runnable {
    int i =10;
    int num = 100;
    boolean flag = true;
    ReentrantLock l = new ReentrantLock(true);
    public void run() {
        while (i >= 1) {
            //加鎖
            //如果當前獲取不到鎖則返回false 不等待繼續執行下面
            if (l.tryLock()) {
                try {
                    flag=false;
                    Thread.sleep(500); //睡眠一會
                    if (i > 0) {
                        System.out.println(Thread.currentThread().getName() + "正在售賣:" + (i--) + "張票");
                    }
                } catch (InterruptedException e) {
//                  e.printStackTrace();
                } finally {
                    flag=true;
                    l.unlock();
                }

            }
     if(flag&&num>0)
{

int i = 5;
// System.out.println(Thread.currentThread().getName());
for (int r = 0 ;r<10;r++){
try {
Thread.sleep(900);
} catch (InterruptedException e) {
e.printStackTrace();
}
// if(i>0)
System.out.println(i--+""+Thread.currentThread().getName());
}
i=5;
}
 } }

得出結論:當線程沒拿到鎖后,會開始執行下面的代碼,且當執行完之后才會繼續去嘗試獲取鎖

 

 如果鎖在給定等待時間內沒有被另一個線程保持,且當前線程未被中斷,則獲取該鎖。

void unlock()釋放鎖,建議放在finally中 避免出現異常導致死鎖的發生。

 

https://www.cnblogs.com/kkxwze/p/11168525.html


免責聲明!

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



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