Java毒丸对象_六、Java“毒丸”使用示例,实现取消任务

一、简介

在Java并发编程中,“毒丸”指的是将一个对象放在队列当中,当得到这个对象的时候立即停止执行

下面是一个使用“毒丸”来取消任务的一个示例

7e6e12e8467c10ef45e27e6e3ec5acd3.png

如图所示,我们假设一个任务从开始到结束需要经历4个步骤,正常情况下4个步骤将会顺序执行。

而在任务的执行过程中,我们由于一些原因需要取消这个任务,那这个时候我们设置一个“毒丸”,每个步骤在执行开始的时候会进行校验,如果遇到“毒丸”那么将终止执行。

考虑到添加“毒丸”的时候,上一个任务可能还在执行中,所以添加毒丸以后,需要对上一个步骤进行清理,例如:上一个步骤是在查询数据库,那么可能你需要把数据库的查询中断掉

二、示例代码

PoisonDemo

public classPoisonDemo {public static voidmain(String[] args) {//实例化一个任务

final Task task = newTask();//另起一个线程,在2秒以后取消任务

new Thread(newRunnable() {public voidrun() {try{

Thread.sleep(2000);

}catch(InterruptedException e) {

e.printStackTrace();

}

task.cancel();

}

}).start();//主线程执行任务

task.execute();

}

}

Task

public classTask {private String[] stepNames = { "step1", "step2", "step3", "step4"};private int currentIndex = 0;private TaskCancelManager manager = newTaskCancelManager();public voidexecute() {

System.out.println("任务开始执行 steps=" +Arrays.asList(stepNames));

Step currStep= null;while (true) {if (currentIndex + 1 >stepNames.length) {break;

}//执行任务

String stepName =stepNames[currentIndex];boolean success =manager.addStep(stepName);if (!success) {

System.out.println(stepName+ " 不继续执行");//清理上一个步骤的数据

if (currStep != null) {

currStep.purge();

}break;

}//获取当前步骤,并执行

currStep = newStep(stepName);

currStep.execute();

currentIndex++;

}

System.out.println("任务执行结束 steps=" +manager.getStepNames());

}public voidcancel() {

manager.addPoison();

}

}

Step

public classStep {privateString stepName;publicStep(String stepName) {this.stepName =stepName;

}public voidexecute() {

System.out.println(stepName+ " 开始执行");try{

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println(stepName+ " 结束执行");

}public voidpurge() {

System.out.println("任务中断,清理" + stepName + "步骤");

}

}

TaskCancelManager:这里采用同步锁来控制添加“毒丸”和“步骤”是互斥的

public classTaskCancelManager {private static final String POISON = "poison";private List stepNames = new ArrayList();public synchronized booleanaddStep(String stepName) {//如果上一个是毒丸

if (stepNames.size() > 0 && stepNames.get(stepNames.size() - 1).equals(POISON)) {return false;

}

stepNames.add(stepName);return true;

}public synchronized voidaddPoison() {

stepNames.add(POISON);

}public ListgetStepNames() {returnstepNames;

}

}

我们运行程序,最后输出内容为:

任务开始执行 steps=[step1, step2, step3, step4]

step1 开始执行

step1 结束执行

step2 开始执行

step2 结束执行

step3 不继续执行

任务中断,清理step2步骤

任务执行结束 steps=[step1, step2, poison]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值