使用观察者模式观察线程的生命周期

来源:互联网 发布:淘宝客招募网站 编辑:程序博客网 时间:2024/05/20 08:41

在线程运行的过程中,外界不能主动获取到其内部的运行状态,而一个线程可以天然的作为一个主题事件被观察者观察。因此可以用观察者模式实现这一目的。

首先定义一个抽象类继承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, stateRUNNING02, stateRUNNING01, stateDONE02, stateERRORjava.lang.ArithmeticException: / by zeroerror!    at com.ran.think.concurrency.Test$2.run(Test.java:27)    at java.lang.Thread.run(Thread.java:745)

可以看出,线程的内部状态已经被观察者处理了

原创粉丝点击