并发设计模式二:多线程观察者模式

转载:https://www.cnblogs.com/luonote/p/10404316.html
关于观察者模式:https://blog.csdn.net/qq_33366098/article/details/88633390

在对观察者模式有了初步的了解后,接下来我们来对更具体的场景进行分析 通过观察者模式去实现如何对一个任务的生命周期进行观察

首先需要定义一个枚举类型

//任务生命周期状态
public enum Cycle {
    STARTED,RUNNING,DONE,ERROR
}

在定义好枚举类型后 定义一个关于任务生命周期的接口 当这个任务发生状态变化hi通知监控者(观察者)时,监控者对应的执行方法相当于上述例子中更新推送时会执行的update方法

public interface TaskLifeCycle<T> {
//这个任务开始时触发的方法
    void onStart(Thread thread);
//这个任务运行时触发的方法
    void onRunning(Thread thread);
//这个任务完成时触发的方法 result为关心的返回值
    void onFinish(Thread thread,T result);
//出现异常时触发的方法 
    void onError(Thread thread, Exception e);
}

接下来定义一个调用者(被观察者)的接口 通过这个接口的实现 来实现整个监控流程的实现被观察的任务会实现这接口 当它发生状态变化时 就会触发上述的方法(意思是会通知观察者)

public interface Observable {

    //获取当前任务的生命周期
    Cycle getCycle();
    //启动线程去监控 还有一个作用是屏蔽Thread的其他API
    void start();
    //对当前监控线程进行打断
    void interrupt();
}

最后定义一个返回值的接口

public interface Task<T> {
//主要是需要关心返回值时调用
    T call();
}

接下来是调用者监控时的具体实现 通过这个方法 会对任务的生命周期进行监控 当任务的生命周期发生变化时 任务就会通知调用者 让调用者执行

public final class ObservableThread<T> extends Thread implements Observable {
  //定义的监控者实现 监控者根据状态变化采取的行动
    private final TaskLifeCycle<T> lifeCycle;
  //返回值
    private final Task<T> task;
  //状态
    private Cycle cycle;

    public ObservableThread(TaskLifeCycle<T> lifeCycle, Task<T> task) {
        //Thread的构造方法
        super();
        if (task == null)
            throw new IllegalArgumentException("Task is not allowed for null");
        this.lifeCycle = lifeCycle;
        this.task = task;
    }
  //更新状态
    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 void run() {
        this.update(Cycle.STARTED, null, null);
        try {this.update(Cycle.RUNNING, null, null);
            TimeUnit.SECONDS.sleep(5); //睡眠5秒模拟工作
            T result = this.task.call();
            this.update(Cycle.DONE, result, null);
        } catch (Exception e) {
            this.update(Cycle.ERROR, null, e); //发生异常时触发的方法
        }
    }
  //获取任务的执行状态
    @Override
    public Cycle getCycle() {
        return this.cycle;
    }
}

接下来简单实现监控者的接口,设立发生状态变化时需要执行的对应方法

public class lifeCycle<T> implements TaskLifeCycle<T> {
    @Override
    public void onStart(Thread thread) {
        System.out.println("i started");
    }

    @Override
    public void onRunning(Thread thread) {
        System.out.println("i am working");
    }

    @Override
    public void onFinish(Thread thread, T result) {
        System.out.println("i finished");
        System.out.println(result);
    }

    @Override
    public void onError(Thread thread, Exception e) {
        System.out.println("i went wrong");
    }
}

测试

public static void main(String[] args) {
        lifeCycle lifeCycle = new lifeCycle();
        ObservableThread observableThread = new ObservableThread(lifeCycle, () -> "任务完成啦");
        observableThread.start();
    }

结果

i started
i am working
i finished
任务完成啦  //定义的返回值

如果在observableThread的run方法中添加一个1/0,结果如下

i started
i am working
i went wrong
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值