十五、JAVA多线程笔记:监控线程的生命周期 (观察者模式)

虽然Thread提供了可获取状态,以及判断是否alive的方法,但是这些方法是针对线程本身的,而我们提交的任务Runnable在运行过程中所处状态是无法直接获得的。
当某一个对象发生状态改变需要通知第三方时,观察者模式就能够胜任这样的工作。


观察者模式需要定义三个接口

代码如下:

package com.zl.step15;


/**
 * 该接口用于返回线程的状态。其中枚举类定义了线程的四个状态。
   start()方法与interrupt()方法用于屏蔽Thread类其他API。
 */
public interface Observable {

    // 任务生命周期的枚举类型
    enum Cycle{
        STARTED,RUNNING,DONE,ERROR
    }
    // 当前任务生命周期状态
    Cycle getCycle();

    //  启动 主要作用:屏蔽Thread的其他方法
    void start();

    // 定义线程打断方法 主要作用:屏蔽Thread的其他方法
    void interrupt();
}
package com.zl.step15;

public interface Task<T> {

    //  任务执行接口,允许有返回值

    T call();
}
package com.zl.step15;


//  定义了任务的生命周期中会被触发的接口
public interface TaskLifecycle<T> {

    // 启动触发
    void onStart(Thread thread);

    // 运行触发
    void onRunning(Thread thread);

    // 完成触发
    void onFinish(Thread thread ,T result);

    // 异常触发
    void onError(Thread thread,Exception e);


    // 生命周期接口的空实现
    class EmptyLifecycle<T> implements TaskLifecycle<T>{

        @Override
        public void onStart(Thread thread) {
            //  do nothing
        }

        @Override
        public void onRunning(Thread thread) {
            //  do nothing
        }

        @Override
        public void onFinish(Thread thread, T result) {
            //  do nothing
        }

        @Override
        public void onError(Thread thread, Exception e) {
            //  do nothing
        }
    }
}
package com.zl.step15;

public class ObservableThread<T> extends Thread implements Observable{

    //  定义了任务的生命周期中会被触发的接口
    private  final  TaskLifecycle lifecycle;

    //任务
    private  final  Task task;

    // 任务生命周期的枚举类型
    private  Cycle cycle;


    // 构造方法 指定Task的实现,默认情况下使用EmptyLifecycle
    public ObservableThread(Task<T> task){
        this(new TaskLifecycle.EmptyLifecycle(),task);
    }
    //构造方法  指定Task Lifecycle
    public ObservableThread(TaskLifecycle lifecycle, Task<T> task) {
        super();
        if(task==null)
            throw  new IllegalArgumentException("The task is required.");
        this.lifecycle = lifecycle;
        this.task = task;
    }

    //重写run方法
    @Override
    public final void run(){
        //先是STARTED状态
        this.update(Cycle.STARTED,null,null);
        try{
            //RUNNING状态
            this.update(Cycle.RUNNING,null,null);
            //执行call方法
            T result = (T) this.task.call();
            //DONE状态
            this.update(Cycle.DONE,result,null);
        }catch (Exception e){
            //ERROR状态
            this.update(Cycle.ERROR,null,e);
        }
    }
    @Override
    //得到线程状态
    public Cycle getCycle() {
        return this.cycle;
    }
    //根据线程不同状态来调用TaskLifecycle中定义的方法
    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;
            }
        }
    }
}
package com.zl.step15;

public class ObservableTest {
    public static void main(String[] args) {
        //实现一个TaskLifecycle接口 并且重写方法,被线程在不同状态下调用
        final TaskLifecycle<Integer> lifecycle = new TaskLifecycle.EmptyLifecycle<Integer>() {
            @Override
            public void onStart(Thread thread) {
                System.out.println("线程准备运行");
            }

            @Override
            public void onRunning(Thread thread) {
                System.out.println("线程正在运行");
            }

            @Override
            public void onFinish(Thread thread, Integer result) {
                System.out.println("线程运行完成 结果为:"+result);
            }

            @Override
            public void onError(Thread thread, Exception e) {
                System.out.println("线程出错");
            }
        };

        Observable o =new ObservableThread<>(lifecycle,()->{
            int a=0;
            for(int i=0;i<10;i++){
                a+=i;
            }
            return a;
        });
        o.start();
    }
}

猜你喜欢

转载自blog.csdn.net/zhanglong_4444/article/details/86236631
今日推荐