利用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();
        }

    }

}

结果:

原文地址:https://www.cnblogs.com/geekdc/p/10298464.html