• JUC中的设计模式


    1. 终止模式之两阶段终止模式

    需求:用一个线程每两秒检测***状态,当不想检测时,用另一个线程将其停止
    在这里插入图片描述

    在一个线程 T1 中如何“优雅”终止线程 T2?这里的【优雅】指的是给 T2 一个料理后事的机会。
    错误思路:

    • 使用线程对象的 stop() 方法停止线程:stop 方法会真正杀死线程,如果这时线程锁住了共享资源,那么当它被杀死后就再也没有机会释放锁,其它线程将永远无法获取锁
    • 使用 System.exit(int) 方法停止线程:目的仅是停止一个线程,但这种做法会让整个程序都停止

    实现方式

    1. 利用isInterrupted实现
      口述:需求是每两秒就检测,而且还可以随时停止,我们定义一个检测方法和停止方法,在这个检测方法中开启一个新的线程来完成检测逻辑,停止方法我们调用检测方法中这个线程的interrupt方法;检测方法中我们需要判断线程是否执行了interrupted,如果执行了的话表示我们要停止检测了,所以berak结束,当没有interrupted的话表示现在还需要检测,然后就检测然后sleep两秒,如果在睡眠中执行了interrupted方法表示我们要停止的话,sleep中的线程在调用interrupted方法会将它的值设置为false而且会抛异常,我们在catch里面再执行一次interrupted方法将其设置为true,那么在下次判断的时候因为现在isinterrupted的值就变为true了,就会进入if内然后break。
      interrupt 可以打断正在执行的线程,无论这个线程是在 sleep,wait还是join(isInterrupted为flase)还是正常运行(isInterrupted为true)
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    2. 同步模式之保护性暂停

    即 Guarded Suspension,一个线程等待另一个线程的执行结果
    要点
    有一个结果需要从一个线程传递到另一个线程,让他们关联同一个 GuardedObject
    JDK 中,join 的实现Future的实现,采用的就是此模式
    因为要等待另一方的结果,因此归类到同步模式

    在这里插入图片描述

    带超时版
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    测试
    在这里插入图片描述
    总结:

    • 唤醒方:notify all + 条件
    • 等待方:while(条件不成立) + wait (剩余等待时间)+ 考虑虚假唤醒,此次唤醒后要计算剩余的等待时间,不能wait(timeout),这样会多等,因为存在虚假唤醒,而因为wait(剩余等待时间)

    join 底层就是用到了这种思路,保护型的暂停模式,暂停指的是当条件不满足时wait等待

    3. 控制不同线程之间的运行次序

    线程 1 输出 a 5 次,线程 2 输出 b 5 次,线程 3 输出 c 5 次。现在要求输出 abcabcabcabcabc 怎么实现?

    Park Unpark 版
    在这里插入图片描述
    在这里插入图片描述
    首先进入打印方法时先都park住,主线程unpark A线程,A线程打印a并且unpark B线程,B线程打印b并unpark C线程,以此类推。
    当然这是用park unpark,当然用wait notify 以及 ReentrantLock里面的条件变量也是可以实现的。

    4. 同步模式之 Balking

    同步模式之 Balking:一个线程发现另一个线程或本线程已经做了某一件相同的事,那么本线程就无需再做了,直接结束返回
    用在:当前端页面多次点击按钮调用 start 时

    在这里插入图片描述

    5. 享元模式

    Boolean,Byte,Short,IntegerLong,Character 等包装类提供了valueOf方法,例如 Long 的valueOf 会缓存 -128~127 之间的 Long 对象,在这个范围之间会重用对象,大于这个范围,才会新建 Long 对象

    口述
    Integer的valueof提供了这种享元模式下的创建方式,其实就是将-128~127之间的Integer对象缓存起来,当创建的是在这个范围就之前返回存储的对应的对象就ok,其实享元的设计思路就是减少创建对象,因为这些都是不可变类,像string啊这些我们在修改时,不会修改原值而是会将char拷贝然后重新new一个出来,在吧new出来的引用赋值,那这样每次修改就会创建,会导致创建的太多了,那享元模式的话就是比如说常用的 值得话我就提前创建好对象放到缓存中,如果在这个范围之内得话你就直接在缓存中拿,不用new了,减少了创建对象得数量。

    6. 异步模式之工作线程

    也体现了经典设计模式中的享元模式,重用线程对象嘛!

    固定大小线程池会有饥饿现象
    在这里插入图片描述

    解决办法:针对不同的任务类型,采用不同的线程池,例如:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    算符与数据结构 --- 类C语言有关操作和补充
    VIAVI唯亚威FI-10/-11 光纤识别仪
    硬件故障诊断:快速定位问题
    学内核之十二:从slab内存管理想到的----之前言
    git2:git概述
    深度强化学习第 1 章 机器学习基础
    如何获取Adreno GPU数据
    Flutter笔记:发布一个电商中文货币显示插件Money Display
    复习单片机:静态数码管(内含1 数码管介绍+2 硬件设计+3 软件设计+4.原始代码+5 实验现象) (注:数码管介绍和硬件设计是重点)
    计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)
  • 原文地址:https://blog.csdn.net/qq_51240148/article/details/133500349