Java多線程問題--使用ReentrantLock類和Condition類實現多線程順序執行

本文內容部分引自《Java多線程編程核心技術》,感謝作者!!!

代碼地址:https://github.com/xianzhixianzhixian/thread.git

原理其實很簡單:使用不同的Condition實例即可,和這篇文章裏的喚醒特定線程有異曲同工之處

https://blog.csdn.net/XIANZHIXIANZHIXIAN/article/details/86484469

多線程順序執行實例

Run.java

/**
 * 使用Condition實現線程的順序執行
 * @author: xianzhixianzhixian
 * @date: 2019-01-22 21:32
 */
public class Run {
    /**
     * 這裏不需要加vloatile關鍵字,因爲lock.lock()、lock.unlock()具有和synchronized一樣的功能:使線程線程工作內存中的
     * 私有變量和公共內存中的變量雙向同步的功能
     */
    volatile private static int nextPrintWho = 1;
    private static ReentrantLock lock = new ReentrantLock();
    final private static Condition conditionA = lock.newCondition();
    final private static Condition conditionB = lock.newCondition();
    final private static Condition conditionC = lock.newCondition();
    public static void main(String[] args) {
        Thread threadA = new Thread() {
            @Override
            public void run() {
                try {
                    lock.lock();
                    while (nextPrintWho != 1){
                        conditionA.await();
                    }
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadA "+(i+1)+" "+Thread.currentThread().getName());
                    }
                    nextPrintWho = 2;
                    conditionB.signalAll();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };

        Thread threadB = new Thread() {
            @Override
            public void run() {
                try {
                    lock.lock();
                    while (nextPrintWho != 2){
                        conditionA.await();
                    }
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadA "+(i+1)+" "+Thread.currentThread().getName());
                    }
                    nextPrintWho = 3;
                    conditionC.signalAll();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };

        Thread threadC = new Thread() {
            @Override
            public void run() {
                try {
                    lock.lock();
                    while (nextPrintWho != 3){
                        conditionA.await();
                    }
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadA "+(i+1)+" "+Thread.currentThread().getName());
                    }
                    nextPrintWho = 1;
                    conditionA.signalAll();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };

        Thread[] aArray = new Thread[5];
        Thread[] bArray = new Thread[5];
        Thread[] cArray = new Thread[5];
        for (int i = 0; i < 5; i++) {
            aArray[i] = new Thread(threadA);
            bArray[i] = new Thread(threadB);
            cArray[i] = new Thread(threadC);
            aArray[i].start();
            bArray[i].start();
            cArray[i].start();
        }
    }
}

運行結果:可以看到多個不同的線程順序打印123

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章