• 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. 异步模式之工作线程

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

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

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

  • 相关阅读:
    LCD12864驱动开发
    【React 一】 入门学习
    计算机毕业设计springboot+vue基本微信小程序的家装公司管理系统小程序
    [附源码]计算机毕业设计springboot课室预约系统
    2023CANN训练营第二季——Ascend C算子开发(入门)——基础概念
    .NET周刊【12月第2期 2023-12-13】
    sql:SQL优化知识点记录(十三)
    超有爱科技携手企企通,打造智慧的数字化采购体系,推动教育数字转型
    35、Java——一个案例学会Dao+service层对数据表的增删改查
    数学建模比赛中常用的建模提示词(数模prompt)
  • 原文地址:https://blog.csdn.net/qq_51240148/article/details/133500349