public class LockTest { // 新建鎖 Lock lock = new ReentrantLock(); public static void main(String[] args) { // 測試 LockTest test = new LockTest(); test.te(); } public void te(){ try { // 獲取鎖 lock.lock(); System.out.println("獲取到鎖執行代碼!"); } catch (Exception e) { e.printStackTrace(); } finally { // 必定注意 在finally中釋放鎖 lock.unlock(); } } }
Lock比synchronized仍是多一些功能的,好比能夠設置規定時間內獲取不到鎖就返回,不一直阻塞。java
一個不合時宜的例子就是:測試
synchronize就是一個舔狗,一直舔 直到天荒地老spa
lock 的 tryLock 就像是一個渣男,輕輕嘗試一下,不合適抓緊下一個code
public class LockTest02 { // 新建鎖 Lock lock = new ReentrantLock(); public static void main(String[] args) { // 測試 LockTest02 test = new LockTest02(); new Thread(()->test.te()).start(); // test::teTryLock lambda寫法 new Thread(test::teTryLock).start(); } private void teTryLock() { boolean res = false; try { // 嘗試獲取 5秒鐘獲取不到就結束 res = lock.tryLock(5,TimeUnit.SECONDS); if (res) { System.out.println("teTryLock獲取到鎖了,執行獲取到鎖的代碼"); } else{ System.out.println("teTryLock沒有獲取到鎖 執行沒有獲取到鎖的代碼"); } } catch (Exception e) { e.printStackTrace(); } finally { // 若是獲取到鎖了 再釋放 if (res) { lock.unlock(); } } } public void te(){ try { // 獲取鎖 lock.lock(); System.out.println("te獲取到鎖執行代碼!"); Thread.sleep(10000); } catch (Exception e) { e.printStackTrace(); } finally { // 必定注意 在finally中釋放鎖 lock.unlock(); System.out.println("te釋放鎖!"); } } } 輸出結果: te獲取到鎖執行代碼! teTryLock沒有獲取到鎖 執行沒有獲取到鎖的代碼 te釋放鎖!
synchronized 若是開始等待是不能結束的隊列
可是Lock使用lockInterruptibly 能夠被中斷 在異常捕獲裏捕獲異常 而後作一些後置處理源碼
public class LockTest03 { // 新建鎖 Lock lock = new ReentrantLock(); public static void main(String[] args) throws InterruptedException { // 測試 LockTest03 test = new LockTest03(); new Thread(test::te).start(); Thread thread = new Thread(test::teLockInterruptibly); thread.start(); Thread.sleep(3000); thread.interrupt(); } private void teLockInterruptibly() { boolean res = true; try { // 嘗試獲取 5秒鐘獲取不到就結束 lock.lockInterruptibly(); System.out.println("獲取到鎖··"); } catch (InterruptedException e) { //沒有正常獲取鎖 被Interrupt了 res = false; System.out.println("InterruptedException:被打斷了 作一些其餘處理"); } finally { // 若是沒被打斷 是正常獲取鎖的(理論上是,也可能有其餘異常) if(res) { lock.unlock(); } } } public void te(){ try { // 獲取鎖 lock.lock(); System.out.println("te獲取到鎖執行代碼!"); // te 方法睡死過去了 Thread.sleep(10000000); } catch (Exception e) { e.printStackTrace(); } finally { // 必定注意 在finally中釋放鎖 lock.unlock(); System.out.println("te釋放鎖!"); } } }
synchronized是非公平鎖 後來的也可能會先獲取到鎖 it
Lock鎖默認也是非公平鎖 io
非公平鎖是什麼樣的?class
用不要臉的小強來作比喻,假設有10我的在排隊買餅,小強這時候也來買餅了,不要臉的他直接跑第一個位置,這時候若是正有人在選餅,那他就灰溜溜的走了,若是上一我的恰好買完,下一我的尚未開始選,那不要臉的小強就會趁着這個間隙直接跟老闆選餅. 這樣對於後邊排隊的是不公平的 因此稱爲不公平鎖thread
在ReentrantLock的實現中,不要臉的小強會嘗試好幾回,最後都失敗的話他纔會去隊尾排隊
Lock能夠實現公平鎖:公平鎖就是lock的時候會先去排隊隊列裏邊看看,有沒有人在排隊,有的話站後邊去,能夠看我寫過的AQS ,用公平鎖作的舉例 講到了源碼層
注意:公平鎖不是徹底公平,公平鎖只是會檢查隊列裏有沒有人排隊,若是沒有本身去申請鎖,若是有本身去排隊,去檢查有沒有人排隊的時候可能會出現不公平(地鐵一我的一大步竄你前邊了),進隊列的時候也可能會出現不公平(地鐵一我的一大步竄你前邊了)
Lock lock = new ReentrantLock(true); // true表示公平
有問題能夠留言哦,也能夠公衆號留言(回覆快):