4.线程间定制化通信 (交替完成规定的工作)

 

案列:启动三个线程,按照如下要求:
AA打印5此,BB打印10次,CC打印15次,一共进行10轮

具体思路:
 每个线程添加一个标志位,是该标志位则执行操作,并且修改为下一个标志位,通知下一个标志 位的线程

创建一个可重入锁private Lock lock = new ReentrantLock();
分别创建三个开锁通知  private Condition c1 = lock.newCondition();(他们能实现指定唤醒)

 (注意)具体资源类中的A线程代码操作
上锁,(执行具体操作(判断、操作、通知),解锁)放于try、finally

注意看注释

/**定制化通信  ( 规定完成工作量,交替)
 *   AA 打印 5 次 , BB打印10次  CC打印15次
 *   完成10次这样的交替
 *  怎么完成呢?  设置标志位,对应线程, 指定唤醒线程
 *  sysnchronzied 是随机唤醒的, Lock 锁创建Condition 可以指定唤醒
 */
class  ShareRes{
    private int flag =1; // 1 AA,  2 BB ,3 CC
    Lock lock = new ReentrantLock(); //一定记得创建可重锁
 
    Condition c1 =lock.newCondition(); //可以指定唤醒线程
    Condition c2 =lock.newCondition();
    Condition c3 =lock.newCondition();
    //注意唤醒的线程,以及标志位, 和线程的start
 
    //指定AA 做的工作 参数:循环次数
    public void AA(int loop) throws InterruptedException {
        //上锁 ,判断 ,干活,通知,解锁
        lock.lock();
      try {
          while (flag != 1) {
              c1.await();
          }
          for (int i = 1; i <= 5; i++) {
              System.out.println(Thread.currentThread().getName() + " ::" + i + "循环的次数" + loop);
          }
          flag = 2; //修改标志位,定向唤醒 线程b
          c2.signal();
      }finally {
          lock.unlock();
      }
    }
 
    //指定AA 做的工作 参数:循环次数
    public void BB(int loop) throws InterruptedException {
        //上锁 ,判断 ,干活,通知,解锁
        lock.lock();
        try {
            while (flag != 2) {
                c2.await();
            }
            for (int i = 1; i <= 10; i++) {
                System.out.println(Thread.currentThread().getName() + " ::" + i + "循环的次数" + loop);
            }
            flag = 3; //修改标志位,定向唤醒 线程b
            c3.signal();
        }finally {
            lock.unlock();
        }
    }
 
    //指定AA 做的工作 参数:循环次数
    public void CC(int loop) throws InterruptedException {
        //上锁 ,判断 ,干活,通知,解锁
        lock.lock();
        try {
            while (flag != 3) {
                c3.await();
            }
            for (int i = 1; i <= 15; i++) {
                System.out.println(Thread.currentThread().getName() + " ::" + i + "循环的次数" + loop);
            }
            flag = 1; //修改标志位,定向唤醒 线程A
            c1.signal();
        }finally {
            lock.unlock();
        }
    }
}
 
public class c01 {
    public static void main(String[] args) {
        ShareRes shareRes = new ShareRes();
 
        new Thread(   //创建三个线程
                () ->{
                    for (int i = 0; i < 10; i++) {
                        try {
                            shareRes.AA(i);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } } }
       ,"AA" ).start();
        new Thread(
                () ->{
                    for (int i = 0; i < 10; i++) {
                        try {
                            shareRes.BB(i);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } } }
                ,"BB" ).start();
        new Thread(
                () ->{
                    for (int i = 0; i < 10; i++) {
                        try {
                            shareRes.CC(i);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } } }
                ,"CC" ).start();
    }
}

posted @ 2022-03-07 11:27  随遇而安==  阅读(32)  评论(0编辑  收藏  举报