• 利用Condition实现多线程交替执行


    一、需求

    • A、B、C 三个线程,循环10次,打印出自己的名称,ABC,ABC,ABC...
    • A、B、C 三个线程,循环10次,打印出自己的名称,A一次,B三次,C五次,ABBBCCCCC,ABBBCCCCC

    1.1、循环打印ABC

    package com.example.demo.juc;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * @author DUCHONG
     * @since 2019-01-21 10:46
     **/
    public class ABC {
    
        public static void main(String[] args) {
    
            PrintDemo pd=new PrintDemo();
            //A 线程
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 1; i <=10 ; i++) {
                        pd.printA(i);
                    }
                }
            },"A").start();
    
            //B 线程
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 1; i <=10 ; i++) {
                        pd.printB(i);
                    }
                }
            },"B").start();
    
            //C 线程
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 1; i <=10 ; i++) {
                        pd.printC(i);
                    }
                }
            },"C").start();
        }
    }
    
    
    class PrintDemo{
    
        Lock lock =new ReentrantLock();
    
        private Condition conditionA=lock.newCondition();
        private Condition conditionB=lock.newCondition();
        private Condition conditionC=lock.newCondition();
    
        //哪个线程等待与否的标记,flag的值:
        // 1 线程A打印,否则等待,同时将标记设置为2,唤醒线程B
        // 2 线程B打印,否则等待,同时将标记设置为3,唤醒线程C
        // 3 线程C打印,否则等待,同时将标记设置为1,唤醒线程A  外层一次循环结束。
        private Integer flag=1;
        //打印A
        public void printA(int loop){
            try{
                lock.lock();
                if(flag!=1){
                    conditionA.await();
                }
    
                for (int i=1;i<=1;i++) {
                    System.out.println(Thread.currentThread().getName() + "---" + loop);
                }
                flag=2;
                conditionB.signal();
            }
            catch(Exception e){
                e.printStackTrace();
            }
            finally {
                lock.unlock();
            }
    
        }
        //打印B
        public void printB(int loop){
            try{
                lock.lock();
                if(flag!=2){
                    conditionB.await();
                }
    
                for (int i=1;i<=1;i++) {
                    System.out.println(Thread.currentThread().getName() + "---" + loop);
                }
    
                flag=3;
                conditionC.signal();
            }
            catch(Exception e){
                e.printStackTrace();
            }
            finally {
                lock.unlock();
            }
    
        }
        //打印C
        public void printC(int loop){
            try{
                lock.lock();
                if(flag!=3){
                    conditionC.await();
                }
    
                for (int i=1;i<=1;i++) {
                    System.out.println(Thread.currentThread().getName() + "---" + loop);
                }
                flag=1;
                conditionA.signal();
            }
            catch(Exception e){
                e.printStackTrace();
            }
            finally {
                lock.unlock();
            }
    
        }
    
    }
    

    结果:

    1.2、循环打印ABBBCCCC

    package com.example.demo.juc;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * @author DUCHONG
     * @since 2019-01-21 14:15
     **/
    public class ABBB {
    
        public static void main(String[] args) {
            PrintABBBDemo pd=new PrintABBBDemo();
            //A 线程
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 1; i <=10 ; i++) {
                        pd.printA(i);
                    }
                }
            },"A").start();
    
            //B 线程
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 1; i <=10 ; i++) {
                        pd.printB(i);
                    }
                }
            },"B").start();
    
            //C 线程
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 1; i <=10 ; i++) {
                        pd.printC(i);
                    }
                }
            },"C").start();
        }
    
    }
    
    class PrintABBBDemo{
    
        Lock lock =new ReentrantLock();
    
        private Condition conditionA=lock.newCondition();
        private Condition conditionB=lock.newCondition();
        private Condition conditionC=lock.newCondition();
    
        //哪个线程等待与否的标记,flag的值:
        // 1 线程A打印,否则等待,同时将标记设置为2,唤醒线程B
        // 2 线程B打印,否则等待,同时将标记设置为3,唤醒线程C
        // 3 线程C打印,否则等待,同时将标记设置为1,唤醒线程A  外层一次循环结束。
        private Integer flag=1;
        //打印A
        public void printA(int loop){
            try{
                lock.lock();
                if(flag!=1){
                    conditionA.await();
                }
    
                for (int i=1;i<=1;i++) {
                    System.out.println(Thread.currentThread().getName() + "---" + loop);
                }
                flag=2;
                conditionB.signal();
            }
            catch(Exception e){
                e.printStackTrace();
            }
            finally {
                lock.unlock();
            }
    
        }
        //打印B
        public void printB(int loop){
            try{
                lock.lock();
                if(flag!=2){
                    conditionB.await();
                }
    
                for (int i=1;i<=3;i++) {
                    System.out.println(Thread.currentThread().getName() + "---" + loop);
                }
    
                flag=3;
                conditionC.signal();
            }
            catch(Exception e){
                e.printStackTrace();
            }
            finally {
                lock.unlock();
            }
    
        }
        //打印C
        public void printC(int loop){
            try{
                lock.lock();
                if(flag!=3){
                    conditionC.await();
                }
    
                for (int i=1;i<=5;i++) {
                    System.out.println(Thread.currentThread().getName() + "---" + loop);
                }
                flag=1;
                conditionA.signal();
            }
            catch(Exception e){
                e.printStackTrace();
            }
            finally {
                lock.unlock();
            }
    
        }
    
    }
    

    结果:

  • 相关阅读:
    深度优先搜索初尝试-DFS-LakeCounting POJ No.2386
    hdoj-2053-Switch Game
    《算法竞赛入门经典》习题及反思 -<2>
    高精度N的阶乘-N!
    列举一些有所帮助的blog和文章
    hdoj-2039-三角形
    hdoj-2035-人见人爱a^b
    hdoj-2028-Lowest common multiple plus
    hdoj上的一题和程序设计第二次作业的拓展-人见人爱a+b
    程序设计第三次作业---C++计算器雏形
  • 原文地址:https://www.cnblogs.com/geekdc/p/10298464.html
Copyright © 2020-2023  润新知