Java-JUC(十):线程按序交替执行 Java:现有线程T1/T2/T3,如何确保T1执行完成之后执行T2,T3在T2执行完成之后执行。

问题:

有a、b、c三个线程,使得它们按照abc依次执行10次。

实现:

package com.dx.juc.test;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ABC {
    public static void main(String[] args) {
        final AlternateDemo alternateDemo=new AlternateDemo();
        
        new Thread(new Runnable() {
            public void run() {
                for(int i=1;i<10;i++){
                    alternateDemo.loopA(i);
                }
            }
        }, "A").start();
        
        new Thread(new Runnable() {
            public void run() {
                for(int i=1;i<10;i++){
                    alternateDemo.loopB(i);
                }
            }
        }, "B").start();
        
        new Thread(new Runnable() {
            public void run() {
                for(int i=1;i<10;i++){
                    alternateDemo.loopC(i);
                    System.out.println("---------------------------------------");
                }
            }
        }, "C").start();
    }
}

class AlternateDemo {
    private Lock lock = new ReentrantLock();

    private Condition conditionA = lock.newCondition();
    private Condition conditionB = lock.newCondition();
    private Condition conditionC = lock.newCondition();

    // 一个标号,标记当前可以执行的线程编号.1-a线程可以执行,2-b线程可以执行,3-c线程可以执行。
    private int flag = 1;

    public void loopA(int loopNum) {
        lock.lock();

        try {
            // 1)等待喚醒
            // 如果flag标记值不是1的话,就让线程处于等待状态,直到其他线程唤醒它。
            if (flag != 1) {
                conditionA.await();
            }

            // 2)被喚醒后,開始執行。
            for (int i = 1; i <= 1; i++) {
                System.out.println(Thread.currentThread().getName() + "-" + loopNum + "-" + i);
            }

            // 3)修改標記flag,并喚醒下一個線程。
            flag = 2;
            conditionB.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void loopB(int loopNum) {
        lock.lock();

        try {
            // 1)等待喚醒
            // 如果flag标记值不是2的话,就让线程处于等待状态,直到其他线程唤醒它。
            if (flag != 2) {
                conditionB.await();
            }

            // 2)被喚醒后,開始執行。
            for (int i = 1; i <= 1; i++) {
                System.out.println(Thread.currentThread().getName() + "-" + loopNum + "-" + i);
            }

            // 3)修改標記flag,并喚醒下一個線程。
            flag = 3;
            conditionC.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void loopC(int loopNum) {
        lock.lock();

        try {
            // 1)等待喚醒
            // 如果flag标记值不是3的话,就让线程处于等待状态,直到其他线程唤醒它。
            if (flag != 3) {
                conditionC.await();
            }

            // 2)被喚醒后,開始執行。
            for (int i = 1; i <= 1; i++) {
                System.out.println(Thread.currentThread().getName() + "-" + loopNum + "-" + i);
            }

            // 3)修改標記flag,并喚醒下一個線程。
            flag = 1;
            conditionA.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

测试打印结果:

A-1-1
B-1-1
C-1-1
---------------------------------------
A-2-1
B-2-1
C-2-1
---------------------------------------
A-3-1
B-3-1
C-3-1
---------------------------------------
A-4-1
B-4-1
C-4-1
---------------------------------------
A-5-1
B-5-1
C-5-1
---------------------------------------
A-6-1
B-6-1
C-6-1
---------------------------------------
A-7-1
B-7-1
C-7-1
---------------------------------------
A-8-1
B-8-1
C-8-1
---------------------------------------
A-9-1
B-9-1
C-9-1
---------------------------------------

更多实现方案:

请参考《Java:现有线程T1/T2/T3,如何确保T1执行完成之后执行T2,T3在T2执行完成之后执行。

猜你喜欢

转载自www.cnblogs.com/yy3b2007com/p/8977265.html