灵感来源于一个猪队友给个人题目java

看到这个,我抓住的关键字是:任何子任务失败,要通知全部子任务执行取消逻辑。dom

这不就是消息广播吗?观察者模式!ide

干活

首先是收听者测试

packagecom.example.broadcast;/*** 每一个节点便是广播者,也是收听者*/

public interfaceListener {/*** 设置调度中心*/

voidsetCenter(DispatchCenter center);/*** 主动通知其它收听者*/

voidnotice(String msg);/*** 本身收到通知的处理逻辑

*@parammsg*/

voidwhenReceived(String msg);/*** 收听者标志:惟一

*@return

*/String identify();

}

而后是调度中心this

packagecom.example.broadcast;/*** 调度中心*/

public interfaceDispatchCenter {/*** 广播

*@paramown 广播的时候,要排除本身

*@parammsg 广播消息*/

voidbroadcast(String own, String msg);/*** 添加收听者

*@paramlistener*/

voidaddListener(Listener listener);

}

调度中心实现spa

packagecom.example.broadcast;importjava.util.Map;importjava.util.concurrent.ConcurrentHashMap;public class DispatchCenterImpl implementsDispatchCenter {private static final Map MAP = new ConcurrentHashMap<>();

@Overridepublic voidbroadcast(String own, String msg) {

MAP.forEach((k,v)->{//不用给本身发通知

if (!k.equals(own)){

v.whenReceived(msg);

}

});

}

@Overridepublic voidaddListener(Listener listener) {

listener.setCenter(this);

MAP.put(listener.identify(), listener);

}

}

剩下三个收听者线程

packagecom.example.broadcast;importjava.util.UUID;public class ListenerA implementsListener {privateDispatchCenter center;privateString identify;publicListenerA() {

identify=UUID.randomUUID().toString();

}

@Overridepublic voidsetCenter(DispatchCenter center) {this.center =center;

}

@Overridepublic voidnotice(String msg) {

center.broadcast(identify, msg);

}

@Overridepublic voidwhenReceived(String msg) {

System.out.println(this.getClass().getName() + "收到消息:" +msg);

}

@OverridepublicString identify() {returnidentify;

}

}

B和C除了类名不同,其余都同样,再也不赘述。目录以下3d

测试

packagecom.example.broadcast;importjava.util.Random;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;public classMain {public static voidmain(String[] args) {

DispatchCenter center= newDispatchCenterImpl();

ListenerA listenerA= newListenerA();

ListenerB listenerB= newListenerB();

ListenerC listenerC= newListenerC();

center.addListener(listenerA);

center.addListener(listenerB);

center.addListener(listenerC);

ExecutorService executorService= Executors.newFixedThreadPool(3);//A触发1条事件

executorService.submit(() ->{int i = 1;while (i > 0){

listenerA.notice(listenerA.getClass().getName()+ "说:我有" + new Random().nextInt(1000000) + "元");

i--;

}

});//B触发2条事件

executorService.submit(() ->{int i = 2;while (i > 0){

listenerB.notice(listenerB.getClass().getName()+ "说:我有" + new Random().nextInt(1000000) + "元");

i--;

}

});//C触发3条事件

executorService.submit(() ->{int i = 3;while (i > 0){

listenerC.notice(listenerC.getClass().getName()+ "说:我有" + new Random().nextInt(1000000) + "元");

i--;

}

});

executorService.shutdown();

}

}

输出:code

流程图

当其中的B节点,发生了错误,除了把本身处理好以外blog

1. 向调度中心发送广播请求,并携带须要的消息

2. 调度中心遍历收听者,挨个通知(执行)每个收听者接受消息的逻辑

关于中止任务

由于题目要求,【快速取消】全部子任务

关于线程中止的方法也有不少:

1. 优雅退出run方法

2. 暴力stop

3. run方法抛出异常

若是说要求,A异常了,B和C收到消息以后,线程当即中止,不能有一点迟疑,说实话我还没想到该怎么作。由于你要知道,实际上的任务的run方法内部,不太多是个while循环,人家可能就是个顺序执行,因此中止标志位的方式,并不适用。

而其它的方法,我也没想到很好的。我只能写个按照标志位中止的“玩具”

修改三个收听者代码和测试类

packagecom.example.broadcast;importlombok.SneakyThrows;importjava.util.Random;importjava.util.UUID;public class ListenerA implementsListener,Runnable {privateDispatchCenter center;privateString identify;publicListenerA() {

identify=UUID.randomUUID().toString();

}

@Overridepublic voidsetCenter(DispatchCenter center) {this.center =center;

}

@Overridepublic voidnotice(String msg) {

center.broadcast(identify, msg);

}

@Overridepublic voidwhenReceived(String msg) {

System.out.println(this.getClass().getName() + "收到消息:" +msg);

}

@OverridepublicString identify() {returnidentify;

}

@SneakyThrows

@Overridepublic voidrun() {//5秒以后,模拟发生异常

Thread.sleep(5000);

notice(this.getClass().getName() + "说:我有" + new Random().nextInt(1000000) + "元");

System.out.println(this.getClass().getName() + "程序异常,并已经传播了消息...");

}

}

packagecom.example.broadcast;importlombok.SneakyThrows;importjava.util.UUID;public class ListenerB implementsListener,Runnable {privateDispatchCenter center;privateString identify;private volatile Boolean stopFlag = false;publicListenerB() {

identify=UUID.randomUUID().toString();

}

@Overridepublic voidsetCenter(DispatchCenter center) {this.center =center;

}

@Overridepublic voidnotice(String msg) {

center.broadcast(identify, msg);

}

@Overridepublic voidwhenReceived(String msg) {

System.out.println(this.getClass().getName() + "_" + Thread.currentThread().getName() + "收到消息:" +msg);//中止当前线程

stopFlag = true;

}

@OverridepublicString identify() {returnidentify;

}

@SneakyThrows

@Overridepublic voidrun() {while (!stopFlag){

Thread.sleep(1000);

System.out.println(this.getClass().getName() + "_" + Thread.currentThread().getName() + "__B在执行任务");

}

System.out.println(this.getClass().getName() + "_" + Thread.currentThread().getName() + "__B Dead");

}

}

packagecom.example.broadcast;importlombok.SneakyThrows;importjava.util.UUID;public class ListenerC implementsListener,Runnable {privateDispatchCenter center;privateString identify;private volatile Boolean stopFlag = false;publicListenerC() {

identify=UUID.randomUUID().toString();

}

@Overridepublic voidsetCenter(DispatchCenter center) {this.center =center;

}

@Overridepublic voidnotice(String msg) {

center.broadcast(identify, msg);

}

@Overridepublic voidwhenReceived(String msg) {

System.out.println(this.getClass().getName() + "_" + Thread.currentThread().getName() + "收到消息:" +msg);//中止当前线程

stopFlag = true;

}

@OverridepublicString identify() {returnidentify;

}

@SneakyThrows

@Overridepublic voidrun() {while (!stopFlag){

Thread.sleep(1000);

System.out.println(this.getClass().getName() + "_" + Thread.currentThread().getName() + "__C在执行任务");

}

System.out.println(this.getClass().getName() + "_" + Thread.currentThread().getName() + "__C Dead");

}

}

测试

packagecom.example.broadcast;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;public classMain {public static voidmain(String[] args) {

DispatchCenter center= newDispatchCenterImpl();

ListenerA listenerA= newListenerA();

ListenerB listenerB= newListenerB();

ListenerC listenerC= newListenerC();

center.addListener(listenerA);

center.addListener(listenerB);

center.addListener(listenerC);

ExecutorService executorService= Executors.newFixedThreadPool(3);//A

executorService.submit(listenerA);//B

executorService.submit(listenerB);//C

executorService.submit(listenerC);

executorService.shutdown();

}

}

这个是这么多年第一个发到首页的,就是想问下你们怎样解决这种状况下的线程中止问题

java 广播模式_Java设计模式——观察者模式的灵活应用相关推荐

  1. java 设置模式_Java设计模式百例 - 调停者模式

    调停者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性的.这种模式提供了一个调停者类,用来充当"中心化"或"总线化"的角色,与各个 ...

  2. java策略模式_Java设计模式之策略模式详解

    本文实例为大家分享了Java策略模式,供大家参考,具体内容如下 1.策略模式(Strategy Pattern)是一种比较简单的模式,也叫做政策模式(PolicyPattern). 定义如下: Def ...

  3. java 行为模式_java设计模式--行为模式

    前言 行为模式是描述多个类与对象之间通过协作共同完成单个对象无法单独完成的任务. 行为模式分为: 类行为模式通过集成在类之间分派行为 对象行为模式通过组合或聚合在对象之间分配行为 行为模式: 模板方法 ...

  4. java 模板模式_java设计模式之模板模式

    模板模式 模板模式(Template Pattern),定义一个操作中算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构,只是重定义该算法的某些特定步骤.这种类型的设计模式属于 ...

  5. java原始模型模式_java设计模式--原始模型模式

    简介 原始模型模式属于对象的创建模式.通过一个原型对象来指明要创建对象的类型,然后用复制原型对象的方法来创建出更多同类型的对象. Java所有的类都是从java.lang.Object类继承来的,Ob ...

  6. java 反射模式_java 设计模式——反射机制的应用

    Java反射机制是指:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java语言 ...

  7. Java创新型模式_java设计模式--创建型模式(一)

    2016-04-24 10:10:34 创建型模式:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式 注意:工厂模式可以分为三类: 1)简单工厂模式(Simple Factory) 2)工厂 ...

  8. java adapter 模式_Java设计模式之适配器模式(Adapter模式)介绍

    适配器模式定义:将两个不兼容的类纠合在一起使用,属于结构型模式,需要有Adaptee(被适配者)和Adaptor(适配器)两个身份. 为何使用适配器模式 我们经常碰到要将两个没有关系的类组合在一起使用 ...

  9. java 外观模式_Java设计模式11:外观模式

    外观模式 外观模式是对象的结构模式,外部与一个子系统的通信必须通过一个统一的外观对象进行.外观模式是一个高层次的接口,使得子系统更易于使用. 医院的例子 现代的软件系统都是比较复杂的.假如把医院比作一 ...

最新文章

  1. vue2 切换路由时 页面滚动到顶部 用游览器返回时 记住上页的位置
  2. 一起再看执行上下文/作用域链/原型链
  3. C#网页数据采集(二)WebBrowser
  4. 重大革新!Dubbo 3.0来了
  5. 第01篇:C#星夜拾遗之如何开始C#学习
  6. php order by where,无合适where条件过滤时尽量选择order by后的字段以驱动表进行查询...
  7. 《北京IT报道》你可以成为下一个《万万没有想到》?
  8. docker-compose.yml模板文件
  9. 设计模式—抽象工厂模式(思维导图)
  10. 6-2-二叉树(二叉链表存储)-树和二叉树-第6章-《数据结构》课本源码-严蔚敏吴伟民版...
  11. keil_lic.exe注册机使用
  12. Truecrypt之死
  13. html怎么置顶图像,css怎么固定图片位置不变?
  14. 小朋友把游戏藏在计算机里,给两、三岁宝宝的60个超简单家庭早教游戏
  15. 嵌入式UI架构设计漫谈
  16. Redis学习之srem命令
  17. 深度学习面试题总结1-20
  18. 2022-01-27 使用liquibase管理mysql执行版本
  19. php 合并对象_PHP合并数组对象
  20. STM32F10xx中独立看门狗(IWDG)和窗口看门狗(WWDG)介绍

热门文章

  1. hashmap原理_HashMap实现原理解读
  2. defaultdict python_理解 Python 语言中的 defaultdict
  3. USTB自习教室查询系统-项目计划书-第二部分
  4. 批量操作权限的页面展示
  5. BZOJ2658 ZJOI2012 小蓝的好友(treap)
  6. MYSQL数据库导入大数据量sql文件失败的解决方案
  7. caffe android lib
  8. Ubuntu 12.04下NFS安装配置
  9. Convert Sorted List to Binary Search Tree ------C++ 递归创建平衡二叉查找树
  10. (转)一段如何調用Button.Click事件的故事