1. 程式人生 > >Java併發程式設計 之 Condition與ReentrantLock的使用

Java併發程式設計 之 Condition與ReentrantLock的使用

先來看一道筆試題(迅雷的筆試題):編寫一個程式,開啟3個執行緒,這3個執行緒的ID分別為A、B、C,每個執行緒將自己的ID在螢幕上列印10遍,要求輸出結果必須按ABC的順序顯示;如:ABCABC….依次遞推。

很明顯考慮這題的時候,需要想到使執行緒之間能夠的進行訊息傳遞。這題如果想要用Object自帶的wait和notify,相比於Condition感覺會更麻煩。wait和notify更容易實現兩個執行緒之間的通訊(生產和消費),而Condition用於多個執行緒之間也可以處理的遊刃有餘。

這篇只是針對Condition和ReentrantLock的如何使用實現原理在下一篇部落格

import
java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; /** * Created by jintx on 2017/9/29. */ public class CondtionTest { public static ReentrantLock lock = new ReentrantLock(); public static Condition conditionA = lock.newCondition(); public static Condition conditionB = lock.newCondition(); public
static Condition conditionC = lock.newCondition(); public static int index = 0; public static void main(String[] args){ ThreadA threadA = new ThreadA(); ThreadB threadB = new ThreadB(); ThreadC threadC = new ThreadC(); threadA.start(); threadB.start(); threadC.start(); } public
static class ThreadA extends Thread{ @Override public void run(){ try{ lock.lock(); for(int i = 1 ; i <= 5; i++) { for (int j = 1; j <= 5; j++) { /*不需要擔心++index同步的問題,因為我們已經保證了每次只能有一個執行緒在++index*/ System.out.println("A程序輸出" + " : " + ++index); } conditionB.signal();//第一次呼叫該方法沒什麼意義,因為執行緒B還沒等待佇列中 conditionA.await();//本質是釋放了對lock的同步控制 } }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } } } public static class ThreadB extends Thread{ @Override public void run(){ try{ lock.lock(); for(int i = 1 ; i <= 5; i++) { for (int j = 1; j <= 5; j++) { System.out.println("B程序輸出" + " : " + ++index); } conditionC.signal(); conditionB.await(); } }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } } } public static class ThreadC extends Thread{ @Override public void run(){ try{ lock.lock(); for(int i = 1 ; i <= 5; i++) { for (int j = 1; j <= 5; j++) { System.out.println("C程序輸出" + " : " + ++index); } conditionA.signal(); conditionC.await(); } }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } } } }