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

news/2024/5/20 7:19:04 标签: java, juc, 并发, 线程定制通信

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

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

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

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

注意看注释

java">/**定制化通信  ( 规定完成工作量,交替)
 *   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();
    }
}

交替完成打印

 

 


http://www.niftyadmin.cn/n/1712930.html

相关文章

4. 集合 的线程安全 (可以看到底层的集合是没有加锁的)

4.1集合不安全的问题 在讲解线程安全的之前&#xff0c;先看线程不安全的 实例 创建 ArrayList集合 并使用线程 再集合中添加元素获取元素 //创建ArrayList集合 List<String> list new ArrayList<>(); for (int i 0; i <30; i) {new Thread(()->{//向集合…

5. 多线程锁 (公平锁和非公平锁,死锁,可重锁)

某一个时刻内&#xff0c;只能有唯一 一个线程去访问这些synchronized 方法 所有的静态同步方法用的也是同一把锁——类对象本身&#xff0c;这两把锁是两个不同的对象&#xff0c;所以静态同步方法与非静态同步方法之间是不会有竞态条件的但是一旦一个静态同步方法获取锁后&am…

JUC高并发编程的学习,知识点详细概括

JUC 的概述 https://blog.csdn.net/qq_52252193/article/details/121903199 一.Lock 接口的概述 1. Lock &#xff08;锁的&#xff09;接口_想成为大神说32的博客-CSDN博客 二.线程间的通信 (Sysnchronized. Lock,的案例&#xff09; 2.什么是线程间的通信 &#xff1f;怎么实…

二叉树的三种遍历算法的实现(前序、中序、后序)递归与非递归

二叉树的三种遍历算法的实现&#xff08;前序、中序、后序&#xff09;递归与非递归 1、二叉树的定义 二叉树是n&#xff08;n>0&#xff09;个数据元素的有限集&#xff0c;含有唯一的称为根的元素&#xff0c;且&#xff0c;其余元素分成两个互不相交的子集&#xff0c;…

6. Callable接口

创建线程的多种方式&#xff1a; 继承Thread类实现Runnable接口Callable接口线程池 目前学习了有两种创建线程的方法&#xff0c;一种是通过创建 Thread 类&#xff0c;另一种是通过使用 Runnable 创建线程&#xff0c;但是&#xff0c;Runnable 缺少的一项功能是&#xff0c;…

数组和指针的几点理解

数组和指针的理解 1.1数组 1.1.1、数组定义 一组具有同名的同属性的数据就组成了一个数组&#xff08;array&#xff09; 由此可以知道&#xff1a; 1、数组是一组有序数据集合。数组中个数据的排列具有一定的规律&#xff0c;下标代表数据在数组中的序号。 int a[10];方括…

7. JUC强大辅助类(减少计数CountDownLatch,循环栅栏CyclicBarrier,信号灯Semaphore)便于解决并发功能

该辅助类主要讲述三个减少计数CountDownLatch 循环栅栏 CyclicBarrier 信号灯Semaphore 7.1 CountDownLatch 该类的构造方法为 CountDownLatch(int count)构造一个用给定计数初始化的CountDownLatch在这里插入代码片 两个常用的主要方法await() 使当前线程在锁存器倒计数至…

队列的数组表示

1、队列的结构特点和操作 复习一下队列&#xff1a;数据结构“队列”与我们日常生活中的排队非常相似&#xff0c;按照先到先办的原则办事&#xff0c;并且严格规定不能加塞&#xff0c;也不允许中途离队。 队列&#xff1a;限定只能在队尾进行插入元素&#xff0c;在表头进行…