Java多執行緒-53-ReentrantLock類-互斥鎖
阿新 • • 發佈:2019-01-13
前面文章末尾,我們提到wait會釋放鎖,而sleep不會釋放鎖。那麼什麼是鎖,鎖就是把執行緒鎖住。也就是執行緒能被鎖住,當然還有釋放鎖。這篇來了解下ReentrantLock類,中文的意思就是互斥鎖。主要學習這個類的lock()獲取鎖和unlock()釋放鎖。
互斥鎖程式碼舉例
我們先來看程式碼,然後來解釋。
package thread; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class ReentrantLock_Demo { public static void main(String[] args) { Printer3 p = new Printer3(); new Thread() { public void run() { while(true) { try { p.print1(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread() { public void run() { while(true) { try { p.print2(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread() { public void run() { while(true) { try { p.print3(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } } class Printer3 { private int flag = 1; private ReentrantLock r = new ReentrantLock(); private Condition c1 = r.newCondition(); private Condition c2 = r.newCondition(); private Condition c3 = r.newCondition(); public void print1() throws InterruptedException { r.lock(); if(flag != 1) { c1.await(); // C1進入等待狀態 } System.out.print("跟"); System.out.print("我"); System.out.print("一"); System.out.print("起"); System.out.println("念"); flag = 2; c2.signal(); // c1等待 喚醒c2 r.unlock(); } public void print2() throws InterruptedException { r.lock(); if(flag != 2) { c2.await(); } System.out.print("做"); System.out.print("測"); System.out.print("試"); System.out.print("死"); System.out.print("路"); System.out.print("一"); System.out.println("條"); flag = 3; c3.signal(); // c2等待,喚醒c3 r.unlock(); } public void print3() throws InterruptedException { r.lock(); if(flag != 3) { c3.await(); } System.out.print("信"); System.out.print("才"); System.out.print("怪"); System.out.println("呢"); flag = 1; c1.signal(); // c3等待,喚醒c1 r.unlock(); } }
執行結果和前面使用同步鎖是一樣的。第一點不同,由前面while語句改成了if語句判斷。第二個不同,由互斥鎖物件r呼叫lock和unlock方法來替代原來的synchronized。第三點不同,三個執行緒之間,喚醒都是很明確的,執行緒1等待喚醒的是執行緒2,執行緒2等待喚醒執行緒3,執行緒3等待喚醒的執行緒1. 這裡使用了互斥鎖的成員方法newCondition(),裡面Condition類有await()方法就是相當於前面學習的wait方法,signal()方法就是前面的notify()方法。互斥鎖比前面的同步程式碼塊功能要強大很多。