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

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

首先定义一个抽象类继承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)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值