概述
一般情况下想要获得线程的最终结果,我们不得不为Thread或者Runable任务执行
在这一章中,我们通过将监听者模式与线程相结合很好地观察到了任务执行的周期,而且还能灵活方便地解决run方法无法获得线程运行后无返回值的问题。
角色
组成(角色) | 作用 |
---|---|
抽象可观察线程接口 (Observable) | 该接口主要暴露给调用者,定义了可观察线程的启动和打断方法 |
生命周期状态枚举类(Cycle) | 定义了可观察线程的几个生命周期状态:开始、运行前、运行结束、发生异常 |
具体可观察线程类 (ObservableThread) | 实现了如何观察线程的各个状态的业务逻辑 |
抽象观察策略接口 (TaskLifecycle) | 定义了观察策略的几个接口方法 |
具体观察策略类 (EmptyTaskLifecycle) | 实现响应的策略接口,这里在接口中提供了一个默认的内部类空实现 |
任务执行单元(Task) | 未在上图中体现,用于替代runnable接口 |
关键代码
Observable :
package chapter1;
/**
* 可观察线程抽象接口
*/
public interface Observable {
//线程任务生命周期的枚举类型
enum Cycle{
STARTED,RUNNING,DONE,ERROR
}
//获取当前任务的生命周期状态
Cycle getCyscle();
//定义启动线程的方法,主要作用是为了屏蔽 Thread的其他方法
void start();
//定义线程的打断方法,作用与 start方法一样,也是为了屏蔽 Thread的其他方法
void interrupt();
}
Task:
package chapter1;
/**
* 任务执行单元
* 此接口用于替代Runnable接口
*/
@FunctionalInterface
public interface Task<T> {
T call();
}
TaskLifecycle:
package chapter1;
/**
* 定义任务的观察监控策略接口
* @param <T>
*/
public interface TaskLifecycle<T> {
//任务启动时会触发onStart方法
void onStart(Thread thread);
//任务正在运行时会触发 oNrunning方法
void onRunning( Thread thread);
//任务运行结東时会触发 onFinish方法,其中resu1t是任务执行结束后的结果
void onFinish ( Thread thread, T result);
//任务执行报错时会触发 onError方法
void onError ( Thread thread, Exception e);
/**
* 内置一个空监控策略的实现
* @param <T>
*/
class EmptyLifecycle<T> implements TaskLifecycle<T>{
@Override
public void onStart(Thread thread) {
System.out.println("default check onStart()");
}
@Override
public void onRunning(Thread thread) {
System.out.println("default check onRunning()");
}
@Override
public void onFinish(Thread thread, T result) {
System.out.println("default check onFinish()");
}
@Override
public void onError(Thread thread, Exception e) {
System.out.println("default check onError()");
}
}
}
ObservableThread:
package chapter1.impl;
import chapter1.Observable;
import chapter1.Task;
import chapter1.TaskLifecycle;
/**
* 可观察线程类的具体实现
*/
public class ObservableThread<T> extends Thread implements Observable {
private final TaskLifecycle<T> lifecycle;
private final Task<T> task;
private Cycle cycle;
//只指定Task的实现,默认对线程的观察方法执行空即可
public ObservableThread(Task<T> task) {
this(new TaskLifecycle.EmptyLifecycle<>(), task);
}
public ObservableThread(TaskLifecycle<T> lifecycle, Task<T> task) {
super();
if(task == null){
throw new IllegalArgumentException("The task is required.");
}
this.lifecycle = lifecycle;
this.task = task;
}
@Override
public 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 e){
this.update(Cycle.ERROR, null, e);
}
}
//执行通知
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 Cycle getCyscle() {
return this.cycle;
}
}
测试过程
测试1
普通执行:
public class TestMain {
public static void main(String[] args) {
//1.普通线程调用,与直接使用Thread类无差别,只不过必须返回一个null,底层调用了默认的观察监控策略
new ObservableThread<>(()->{
System.out.println("Thread-1 is running");
return null;
}).start();
}
执行结果:
default check onStart()
default check onRunning()
Thread-1 is running
default check onFinish()
修改观察策略:
public class TestMain {
public static void main(String[] args) {
//2.重写默认的线程观察监控策略
TaskLifecycle.EmptyLifecycle<String> emptyLifecycle = new TaskLifecycle.EmptyLifecycle<String>(){
@Override
public void onFinish(Thread thread, String result) {
System.out.println("my check onFinish");
}
};
new ObservableThread<>(emptyLifecycle,()->{
System.out.println("Thread-2 is running");
return null;
}).start();
}
}
执行结果:
default check onStart()
default check onRunning()
Thread-2 is running
my check onFinish
- 代码下载地址:gitee