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