1. 程式人生 > 其它 >Lock和Condition(上):隱藏在併發包中的管程

Lock和Condition(上):隱藏在併發包中的管程

1)管程在SDK包中是怎樣實現的?

  • 靠Lock和Condition介面,Lock用來解決互斥的問題 ,Condition用來解決同步的問題。

2)java語言層面已經有sychronized來 實現管程了,那為什麼我們的sdk工具包中還要再實現一遍管程,直接用sychronized不就行了嗎?

  • sychronized這個語言層面的設計是有瑕疵的,我們說解決死鎖有個方法:破壞不可強行剝奪條件。那我們的sychrnized他如果獲取不到資源,他會帶著已申請到的資源進入阻塞佇列去排隊,如果他帶進去的資源剛好是另外一個執行緒苦苦等待的,那就可能造成死鎖 。

3)怎樣去優化我們synchronized修飾的執行緒帶著資源進阻塞佇列排隊這個問題呢?

  • 首先這個 排隊執行緒要 能夠收得到訊息 ,對應計算機層面就是響應中斷。

  • 其次啊,要讓它能夠有個超時機制,獲取不到進一步資源的話,再等等嘛,實在等不到返回個錯誤也行,就是不要帶著已有資源去阻塞佇列睡大覺 。讓別人也不好過。

  • 最後可不可以設計成如果獲取不到進一步的資源,不要進入阻塞佇列,而是直接返回,並且交出已有資源。

4)上面的三個設計方案對應到我們的SDK工具包之中是怎樣實現的?

 
 // 支援中斷的API
 void lockInterruptibly()
   throws InterruptedException;
 // 支援超時的API
 boolean tryLock(long time, TimeUnit unit)
   throws InterruptedException;
 // 支援非阻塞獲取鎖的API
 boolean tryLock();

5)我們說sychronized保證可見性是根據happen-before規則,那現在工具包中的這些設計是如何保證可見性的呢?

  • ReentrantLock底層有一個volatile型別的成員變數state。加鎖和解鎖之前都去讀一下這個變數,從而就利用volitile來保證可見性。

6)什麼是可重入鎖呢?

  • 可以巢狀使用的鎖

     A加鎖{
      A又加鎖{
      }
     }

7)什麼是公平鎖和非公平鎖?

  • 在佇列中排隊,如果cpu空閒的時候,是排在第一個的 先去 用那就是公平鎖,否則就是不公平的鎖。

  • 對應到具體程式碼,我們的reentrantLock可以帶布林型別的引數,true的話就是一把公平鎖,false或者不填就是一把不公平的鎖 。

8)關於鎖,老前輩們有哪些最佳實踐方案?

  • 在更新一個物件的共享變數的時候需要上把鎖。

  • 在讀取一個共享變數的時候也需要上把鎖。

  • 在呼叫其它物件的方法的時候千萬不要用鎖,萬一他這個物件方法裡面有一些操作,可能會造成死鎖。