Java併發程式設計 之 Condition與ReentrantLock的使用
阿新 • • 發佈:2019-01-09
先來看一道筆試題(迅雷的筆試題):編寫一個程式,開啟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();
}
}
}
}