• Java-JUC(十):线程按序交替执行


    问题:

    有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执行完成之后执行。

  • 相关阅读:
    javascript的函数调用什么时候加括号、什么时候不加括号
    妙味——JS学前预热03
    妙味——JS学前预热02
    妙味——JS学前预热01
    springbootday06 mysql
    springboot04 Ajax json Jquery
    springboot02 Thymeleaf
    springbootDay03 cookie和session 购物车技术
    Linux 基本命令
    NodeJs06 高并发
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/8977265.html
Copyright © 2020-2023  润新知