JUC-執行緒間定製化通訊

2020-08-09 10:18:44

預設的情況下cpu是在隨機切換執行緒,那你郵箱多個執行緒可以有規律的執行,那麼多執行緒之間需要一些協調通訊;

Demo:多執行緒按照順序呼叫:A->B->C

三個執行緒啓動,要求:

  • AA答應5次,BB答應10次,CC列印15次
  • 接着
  • AA答應5次,BB答應10次,CC列印15次
  • 就這樣重複10輪

需要執行緒按照這就涉及到號志:
在这里插入图片描述

實現:

/**
* 多執行緒按循序呼叫,實現A->B->C
 * 三個執行緒啓動,要求:
 * AA答應5次,BB答應10次,CC列印15次
 * 接着
 * AA答應5次,BB答應10次,CC列印15次
 * ..
 * 就這樣重複10輪
*
*
* @Author:LRC
* @Date:9:37 上午 2020/7/4
*/

class ShareData{
    private int num = 1;//當爲1的時候對應AA,2:BB,3:CC
    private Lock lock = new ReentrantLock();
    private Condition cd1 = lock.newCondition();
    private Condition cd2 = lock.newCondition();
    private Condition cd3 = lock.newCondition();

    public void print5(int total){
        lock.lock();
        try {
            //判斷
            while (num!=1){
                cd1.await();
            }
            //幹活
            for (int i = 1; i <=5 ; i++) {
                System.out.println(Thread.currentThread().getName()+":\t"+ total+"\t"+i);
            }
            num=2;
            //通知
            cd2.signal();

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }

    }
    public void print10(int total){
        lock.lock();
        try {
            //判斷
            while (num!=2){
                cd2.await();
            }
            //幹活
            for (int i = 1; i <=10 ; i++) {
                System.out.println(Thread.currentThread().getName()+":\t"+ total+"\t"+i);
            }
            num=3;
            //通知
            cd3.signal();

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    public void print15(int total){
        lock.lock();
        try {
            //判斷
            while (num!=3){
                cd3.await();
            }
            //幹活
            for (int i = 1; i <=15 ; i++) {
                System.out.println(Thread.currentThread().getName()+":\t"+ total+"\t"+i);
            }
            num=1;
            //通知
            cd1.signal();

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }


}


public class ThreadOrderAccess {
    public static void main(String[] args) {
        ShareData shareData = new ShareData();
        new Thread(()->{
            for (int i = 1; i <= 10 ; i++) {
                shareData.print5(i);
            }
        },"AA").start();
        new Thread(()->{
            for (int i = 1; i <= 10 ; i++) {
                shareData.print10(i);
            }
        },"BB").start();
        new Thread(()->{
            for (int i = 1; i <= 10 ; i++) {
                shareData.print15(i);
            }
        },"CC").start();



    }
}

1、有順序通知,需要有標識位
2、有一個鎖Lock,3把鑰匙Condition
3、判斷標誌位
4、輸出執行緒名+第幾次+第幾輪
5、修改標誌位,通知下一個