当某个对象发生状态改变需要通知第三方的时候,观察者模式就特别适合胜任这样的工作。
以线程Thread为例,将任务执行的每个阶段通知给观察者
定义Observable接口
public interface Observable {
/**
* 任务生命周期
*/
enum Cycle {
STARTED, RUNNING, DONE, ERROR
}
/**
* 获取当前任务生命周期状态
*
* @return
*/
Cycle getCycle();
/**
* 定义线程启动方法,主要作用是为了屏蔽Thread的其他方法
*/
void start();
/**
* 定义线程打断方法,也是为了屏蔽Thread的其他方法
*/
void interrupt();
}
该接口主要暴露给调用者使用,四个枚举类型分别代表当前任务执行的阶段
定义TaskLifeCycle接口
public interface TaskLifeCycle<T> {
/**
* 任务启动时触发
*
* @param thread
*/
void onStart(Thread thread);
/**
* 任务运行时触发
*
* @param thread
*/
void onRunning(Thread thread);
/**
* 任务完成时触发
*
* @param thread
* @param result
*/
void onFinish(Thread thread, T result);
/**
* 任务报错时触发
*
* @param thread
* @param ex
*/
void onError(Thread thread,Exception ex);
}
该接口定义了任务执行的生命周期该被触发的方法
DefaultLifeCycle
public class DefaultLifeCycle<T> implements TaskLifeCycle<T> {
@Override
public void onStart(Thread thread) {
System.out.println("任务启动成功");
}
@Override
public void onRunning(Thread thread) {
System.out.println("任务正在运行");
}
@Override
public void onFinish(Thread thread, T result) {
System.out.println("任务运行完成");
if (!Objects.isNull(result)) System.out.println("运行结果为:" + result);
}
@Override
public void onError(Thread thread, Exception ex) {
System.out.println("任务运行出错:" + ex.getMessage());
}
}
该类是为TaskLifeCycle的默认实现
Task接口定义
@FunctionalInterface
public interface Task<T> {
/**
* 任务执行接口,该接口允许有返回值
*
* @return
*/
T call();
}
该接口类似与Runnable接口,负责任务逻辑执行单元
ObservableThread实现
import java.util.Objects;
public class ObservableThread<T> extends Thread implements Observable {
private final TaskLifeCycle<T> lifeCycle;
private final Task<T> task;
private Cycle cycle;
/**
* 指定Task实现,默认情况下使用DefaultLifeCycle
*
* @param task
*/
public ObservableThread(Task<T> task) {
this(new DefaultLifeCycle<T>(), task);
}
/**
* 指定TaskLifeCycle实现与Task实现
*
* @param lifeCycle
* @param task
*/
public ObservableThread(TaskLifeCycle<T> lifeCycle, Task<T> task) {
if (Objects.isNull(task)) throw new IllegalArgumentException("The task is required");
this.lifeCycle = lifeCycle;
this.task = task;
}
/**
* 修饰为final,不允许子类再次对其进行重写,导致整个生命周期监控失效
*/
@Override
public final void run() {
//在执行线程逻辑单元的时候,分别触发相应的事件
this.update(Cycle.STARTED, null, null);
try {
this.update(Cycle.RUNNING, null, null);
T result = this.task.call();
this.update(Cycle.DONE, result, null);
} catch (Exception ex) {
this.update(Cycle.ERROR, null, ex);
}
}
/**
* 触发事件
*
* @param cycle
* @param result
* @param ex
*/
private void update(Cycle cycle, T result, Exception ex) {
this.cycle = cycle;
if (Objects.isNull(lifeCycle)) 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(), ex);
break;
}
}
} catch (Exception e) {
//如果在响应事件时出现异常,则什么也不做,保证任务正常执行,如果是任务运行时出现了错误,则抛出
if (cycle == Cycle.ERROR) {
throw e;
}
}
}
@Override
public Cycle getCycle() {
return this.cycle;
}
}
重写父类的run方法,触发不同阶段该触发的方法。修饰为final,不允许子类再次对其进行重写,导致整个生命周期监控失效
测试1
public static void main(String[] args) {
ObservableThread observableThread = new ObservableThread(() -> {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 112;
});
observableThread.start();
}
输出结果
任务启动成功
任务正在运行
任务运行完成
运行结果为:112
测试2
public static void main(String[] args) {
TaskLifeCycle taskLifeCycle = new DefaultLifeCycle() {
@Override
public void onFinish(Thread thread, Object result) {
System.out.println("重写任务完成监听,运行结果为:" + result);
}
};
ObservableThread observableThread = new ObservableThread(taskLifeCycle, () -> {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 112;
});
observableThread.start();
}
输出结果
任务启动成功
任务正在运行
重写任务完成监听,运行结果为:112