转载:https://www.cnblogs.com/luonote/p/10404316.html
关于观察者模式:https://blog.csdn.net/qq_33366098/article/details/88633390
在对观察者模式有了初步的了解后,接下来我们来对更具体的场景进行分析 通过观察者模式去实现如何对一个任务的生命周期进行观察
首先需要定义一个枚举类型
//任务生命周期状态
public enum Cycle {
STARTED,RUNNING,DONE,ERROR
}
在定义好枚举类型后 定义一个关于任务生命周期的接口 当这个任务发生状态变化hi通知监控者(观察者)时,监控者对应的执行方法相当于上述例子中更新推送时会执行的update方法
public interface TaskLifeCycle<T> {
//这个任务开始时触发的方法
void onStart(Thread thread);
//这个任务运行时触发的方法
void onRunning(Thread thread);
//这个任务完成时触发的方法 result为关心的返回值
void onFinish(Thread thread,T result);
//出现异常时触发的方法
void onError(Thread thread, Exception e);
}
接下来定义一个调用者(被观察者)的接口 通过这个接口的实现 来实现整个监控流程的实现被观察的任务会实现这接口 当它发生状态变化时 就会触发上述的方法(意思是会通知观察者)
public interface Observable {
//获取当前任务的生命周期
Cycle getCycle();
//启动线程去监控 还有一个作用是屏蔽Thread的其他API
void start();
//对当前监控线程进行打断
void interrupt();
}
最后定义一个返回值的接口
public interface Task<T> {
//主要是需要关心返回值时调用
T call();
}
接下来是调用者监控时的具体实现 通过这个方法 会对任务的生命周期进行监控 当任务的生命周期发生变化时 任务就会通知调用者 让调用者执行
public final class ObservableThread<T> extends Thread implements Observable {
//定义的监控者实现 监控者根据状态变化采取的行动
private final TaskLifeCycle<T> lifeCycle;
//返回值
private final Task<T> task;
//状态
private Cycle cycle;
public ObservableThread(TaskLifeCycle<T> lifeCycle, Task<T> task) {
//Thread的构造方法
super();
if (task == null)
throw new IllegalArgumentException("Task is not allowed for null");
this.lifeCycle = lifeCycle;
this.task = task;
}
//更新状态
private void update(Cycle cycle, T result, Exception e) {
this.cycle = cycle;
if (lifeCycle == null) {
return;
}
try {
switch (cycle) {
case STARTED:
this.lifeCycle.onStart(currentThread());
break;
case RUNNING:
this.lifeCycle.onRunning(currentThread());
break;
case DONE:
this.lifeCycle.onFinish(currentThread(), result);
break;
case ERROR:
this.lifeCycle.onError(currentThread(), e);
break;
}
} catch (Exception ex) {
if (cycle == Cycle.ERROR) {
throw ex;
}
}
}
//被监控的任务的逻辑实现单元 它执行到哪一个阶段就会触发相应的方法,即监控者定义的方法
@Override
public void run() {
this.update(Cycle.STARTED, null, null);
try {this.update(Cycle.RUNNING, null, null);
TimeUnit.SECONDS.sleep(5); //睡眠5秒模拟工作
T result = this.task.call();
this.update(Cycle.DONE, result, null);
} catch (Exception e) {
this.update(Cycle.ERROR, null, e); //发生异常时触发的方法
}
}
//获取任务的执行状态
@Override
public Cycle getCycle() {
return this.cycle;
}
}
接下来简单实现监控者的接口,设立发生状态变化时需要执行的对应方法
public class lifeCycle<T> implements TaskLifeCycle<T> {
@Override
public void onStart(Thread thread) {
System.out.println("i started");
}
@Override
public void onRunning(Thread thread) {
System.out.println("i am working");
}
@Override
public void onFinish(Thread thread, T result) {
System.out.println("i finished");
System.out.println(result);
}
@Override
public void onError(Thread thread, Exception e) {
System.out.println("i went wrong");
}
}
测试
public static void main(String[] args) {
lifeCycle lifeCycle = new lifeCycle();
ObservableThread observableThread = new ObservableThread(lifeCycle, () -> "任务完成啦");
observableThread.start();
}
结果
i started
i am working
i finished
任务完成啦 //定义的返回值
如果在observableThread的run方法中添加一个1/0,结果如下
i started
i am working
i went wrong