亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺析JAVA Lock鎖原理

 更新時間:2020年07月23日 11:14:57   作者:呼嚕葫蘆  
這篇文章主要介紹了JAVA Lock鎖原理的相關資料,文中講解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下

同樣是鎖,先說說synchronized和lock的區(qū)別:

  1. synchronized是java關鍵字,是用c++實現(xiàn)的;而lock是用java類,用java可以實現(xiàn)
  2. synchronized可以鎖住代碼塊,對象和類,但是線程從開始獲取鎖之后開發(fā)者不能進行控制和了解;lock則用起來非常靈活,提供了許多api可以讓開發(fā)者去控制加鎖和釋放鎖等等。

寫個Demo

static Lock lock = new ReentrantLock();public static void main(String[] args) throws InterruptedException {


    lock.lock();//其他沒拿到鎖的卡住不動

    Thread thread = new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("start to get lock Interruptibly");
        lock.unlock(); //看看會發(fā)生什么,注釋掉再看看
        lock.lock();
        System.out.println("拿到鎖");
        lock.unlock();
        System.out.println("釋放鎖");
      }
    });
    thread.start();

    Thread.sleep(3000);
    lock.unlock();
  }

我們自己來手寫一下lock接口的tryLock()、lock()和unLock()方法,實現(xiàn)我們自己的myLock。

public class MyLock implements Lock {
  //多并發(fā)調用 0-未占用 大于0-占用
  AtomicInteger state = new AtomicInteger();

  Thread ownerThread = new Thread();

  //等待鎖的隊列
  LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue();

  @Override
  public void lock() {
    if (!tryLock()) { //先搶鎖,所以是非公平鎖
      //沒拿到鎖,放到隊列中去進行排隊
      waiters.add(Thread.currentThread());
      //等待被喚醒
      for (; ; ) {
        if (tryLock()) { //非公平鎖情況下,喚醒過來繼續(xù)獲取鎖
          waiters.poll(); //獲取鎖成功把自己從隊列中取出來
          return;
        } else  //獲取鎖失敗
          LockSupport.park(); //線程阻塞
      }
    }
  }


  @Override
  public boolean tryLock() {
    if (state.get() == 0) { //如果鎖沒被占用
      if (state.compareAndSet(0, 1)) { //如果成功拿到鎖
        ownerThread = Thread.currentThread();  //占用鎖線程改為當前線程
        return true;
      }
    }
    return false;
  }

  @Override
  public void unlock() {

    if (ownerThread != Thread.currentThread()) //占用鎖線程不是當前線程無法釋放鎖
      throw new RuntimeException("非法調用,當前鎖不屬于你");

    if (state.decrementAndGet() == 0) //如果成功釋放鎖
      ownerThread = null; //占用鎖線程置空
    //通知其他線程
//    Thread thread = null;
//
//    while ((thread = waiters.peek()) != null)
//      LockSupport.unpark(thread);
    Thread thread = waiters.peek(); //獲取隊列頭部線程,線程還留在隊列中
    if (thread != null) {
      LockSupport.unpark(thread); //取消阻塞
    }
  }



  @Override
  public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
    return false;
  }


  @Override
  public Condition newCondition() {
    return null;
  }

  @Override
  public void lockInterruptibly() throws InterruptedException {

  }
}

幾個注意點:

  • 鎖的占用狀態(tài)state是AtomicInteger類型,底層原理是CAS,這是為了保證在多并發(fā)情況下線程安全問題;
  • 當線程1釋放鎖成功時,獲取隊列頭部線程但并不取出,因為非公平鎖模式下,隊列頭部線程不一定能獲取到鎖;
  • LockSupport的park()和unPark()方法是native方法,可以阻塞,喚醒線程;

Lock默認是非公平鎖,上面實現(xiàn)的也是非公平鎖,小伙伴們可以試一試。

公平鎖和非公平鎖區(qū)別:

先等待先獲取鎖是公平鎖;先等待也不一定先獲取鎖,可能被突然到來的線程獲取到是非公平鎖;

公平鎖的實現(xiàn):

@Override
  public void lock() {
    checkQueue();//線程來的時候先不獲取鎖,而是先檢查隊列中有沒有等待的線程,如果有,直接放入隊列,如果沒有,再去獲取鎖
    if (!tryLock()) { //先搶鎖,所以是非公平鎖
      //沒拿到鎖,放到隊列中去進行排隊
      waiters.add(Thread.currentThread());
      //等待被喚醒
      for (; ; ) {
        if (tryLock()) { //非公平鎖情況下,喚醒過來繼續(xù)獲取鎖
          waiters.poll(); //獲取鎖成功把自己從隊列中取出來
          return;
        } else  //獲取鎖失敗
          LockSupport.park(); //線程阻塞
      }
    }
  }

看完的小伙伴可以去看JDK提供的Lock源碼啦。。

以上就是淺析JAVA Lock鎖原理的詳細內容,更多關于JAVA Lock鎖原理的資料請關注腳本之家其它相關文章!

相關文章

  • 詳解Mybatis中的 ${} 和 #{}區(qū)別與用法

    詳解Mybatis中的 ${} 和 #{}區(qū)別與用法

    這篇文章主要介紹了Mybatis中的 ${} 和 #{}區(qū)別與用法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Java實現(xiàn)動態(tài)代理

    Java實現(xiàn)動態(tài)代理

    本文給大家介紹的是java使用動態(tài)代理類實現(xiàn)動態(tài)代理的方法和示例,這里推薦給大家,有需要的小伙伴參考下吧
    2015-02-02
  • java8新特性之stream流中reduce()求和知識總結

    java8新特性之stream流中reduce()求和知識總結

    今天帶大家回顧Java8的新特性,文中對stream流中reduce()求和的相關知識作了詳細的介紹,對正在學習java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • 解決mapstruct在eclipse生成不了mapper的實現(xiàn)類問題

    解決mapstruct在eclipse生成不了mapper的實現(xiàn)類問題

    這篇文章主要介紹了解決mapstruct在eclipse生成不了mapper的實現(xiàn)類問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • spring消息轉換器使用詳解

    spring消息轉換器使用詳解

    這篇文章主要為大家詳細介紹了spring消息轉換器的使用,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • java使用Filter實現(xiàn)自動登錄的方法

    java使用Filter實現(xiàn)自動登錄的方法

    這篇文章主要為大家詳細介紹了java使用Filter實現(xiàn)自動登錄的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • springboot如何連接兩個數(shù)據(jù)庫(多個)

    springboot如何連接兩個數(shù)據(jù)庫(多個)

    這篇文章主要介紹了springboot如何連接兩個數(shù)據(jù)庫(多個),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • springboot中報錯Invalid character found in the request的解決

    springboot中報錯Invalid character found in 

    這篇文章主要介紹了springboot中報錯Invalid character found in the request的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • MyBatis學習教程(六)-調用存儲過程

    MyBatis學習教程(六)-調用存儲過程

    這篇文章主要介紹了MyBatis學習教程(六)-調用存儲過程的相關資料,非常不錯,具有參考借鑒價值,感興趣的朋友一起看下吧
    2016-05-05
  • Netty搭建WebSocket服務器實戰(zhàn)教程

    Netty搭建WebSocket服務器實戰(zhàn)教程

    這篇文章主要介紹了Netty搭建WebSocket服務器實戰(zhàn),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-03-03

最新評論