在线程运行的过程中,外界不能主动获取到其内部的运行状态,而一个线程可以天然的作为一个主题事件被观察者观察。因此可以用观察者模式实现这一目的。
首先定义一个抽象类继承Runnable接口,用于构造运行线程和观察者的构造
public abstract class ObservableRunnable implements Runnable {
protected LifeCycleListener listener;
public ObservableRunnable(final LifeCycleListener lifeCycleListener) {
this.listener = lifeCycleListener;
}
public void notifyObserver(RunnableEvent event) {
listener.onEvent(event);
}
public enum RunnableState {
RUNNING, DONE, ERROR;
}
public static class RunnableEvent {
private RunnableState state;
private Thread thread;
private Throwable throwable;
public RunnableEvent(RunnableState state, Thread thread, Throwable cause) {
this.state = state;
this.thread = thread;
this.throwable = cause;
}
public RunnableState getState() {
return state;
}
public void setState(RunnableState state) {
this.state = state;
}
public Thread getThread() {
return thread;
}
public void setThread(Thread thread) {
this.thread = thread;
}
public Throwable getThrowable() {
return throwable;
}
public void setThrowable(Throwable throwable) {
this.throwable = throwable;
}
}
}
LifeCycleListener作为观察者,并有一个notifyObserver方法。线程在运行过程中如果状态改变,就调用LifeCycleListener的onEvent方法,将线程运行的信息作为参数回调观察者。
LifeCycleListener如下
public interface LifeCycleListener {
void onEvent(ObservableRunnable.RunnableEvent event);
}
实现类
public class ThreadLifeCycleListener implements LifeCycleListener {
private final Object lock = new Object();
@Override
public void onEvent(ObservableRunnable.RunnableEvent event) {
synchronized (lock) {
System.out.println(event.getThread().getName() + ", state" + event.getState());
if (event.getThrowable() != null) {
System.out.println("error!");
event.getThrowable().printStackTrace();
}
}
}
}
这里只是简单的打印,实际可以拿到运行线程的状态做一些操作.由于观察者可能不仅仅只观察一个线程,因此需要将onEvent方法做同步处理。
测试类
public class Test {
public static void main(String[] args) {
ThreadLifeCycleListener lifeCycleListener = new ThreadLifeCycleListener();
ObservableRunnable o1 = new ObservableRunnable(lifeCycleListener) {
@Override
public void run() {
try {
notifyObserver(new RunnableEvent(RunnableState.RUNNING, Thread.currentThread(), null));
Thread.sleep(1000);
notifyObserver(new RunnableEvent(RunnableState.DONE, Thread.currentThread(), null));
} catch (Exception e) {
notifyObserver(new RunnableEvent(RunnableState.ERROR, Thread.currentThread(), e));
}
}
};
ObservableRunnable o2 = new ObservableRunnable(lifeCycleListener) {
@Override
public void run() {
try {
notifyObserver(new RunnableEvent(RunnableState.RUNNING, Thread.currentThread(), null));
Thread.sleep(2000);
int i = 1 / 0;
notifyObserver(new RunnableEvent(RunnableState.DONE, Thread.currentThread(), null));
} catch (Exception e) {
notifyObserver(new RunnableEvent(RunnableState.ERROR, Thread.currentThread(), e));
}
}
};
new Thread(o1, "01").start();
new Thread(o2, "02").start();
}
}
测试类中,定义一个观察者,两个活动线程。然后运行,让观察者记录这两个线程的运行状态。
结果如下
01, stateRUNNING
02, stateRUNNING
01, stateDONE
02, stateERROR
java.lang.ArithmeticException: / by zero
error!
at com.ran.think.concurrency.Test$2.run(Test.java:27)
at java.lang.Thread.run(Thread.java:745)
可以看出,线程的内部状态已经被观察者处理了