再话设计模式-使用命令模式实现多线程

1 说明

      在《设计模式-行为型设计模式》文章中的4.9章节(https://blog.csdn.net/weixin_37624828/article/details/106059837)已经提到命令模式是如何编写的,并拿股票交易场景编写了一个例子,最近在看书的过程中对命令模式又有了新的认识,这次就再聊一聊命令模式以及应用。
       命令模式与众多设计模式相比是很简单的,整体实现思想就是定义一个接口并定义这个接口的诸多实现,然后将其放入一个集合中,执行该集合。调用者并不关心执行的内容是什么,因为集合中的元素都实现了相同的接口。
      本文介绍一种使用主动对象模式与命令模式相结合的方式实现一个多线程的程序。

2 例子

代码清单:

  1. Command.java --接口
  2. SleepCommand.java
  3. ActiveObjectEngine.java
  4. DelayedTyper.java

1 Command.java

public interface Command {
    void execute();
}

2 SleepCommand.java

public class SleepCommand implements Command {
    private Command wakeupCommand = null;
    private ActiveObjectEngine engine = null;
    private long sleepTime = 0;
    private long startTime = 0;
    private boolean started = false;

    public SleepCommand(long milliseconds, ActiveObjectEngine e, Command wakeupCommand) {
        sleepTime = milliseconds;
        engine = e;
        this.wakeupCommand = wakeupCommand;
    }

    @Override
    public void execute() {
        long currentTime = System.currentTimeMillis();
        if (!started) {
            started = true;
            startTime = currentTime;
            engine.addCommand(this);
        } else if ((currentTime - startTime) < sleepTime) {
            engine.addCommand(this);
        } else {
            engine.addCommand(wakeupCommand);
        }
    }
}

3 ActiveObjectEngine.java

public class ActiveObjectEngine {
    private boolean stop = false;

    LinkedList itsCommands = new LinkedList();


    public void addCommand(Command c) {
        itsCommands.add(c);
    }

    public void run() {
        while (!itsCommands.isEmpty()) {
            Command c = (Command) itsCommands.getFirst();
            itsCommands.removeFirst();
            c.execute();
        }
    }

    public void stop(){
        this.stop = true;
    }
}

4 DelayedTyper.java

public class DelayedTyper implements Command {
    private long itsDelay;
    private char itsChar;
    private static ActiveObjectEngine engine = new ActiveObjectEngine();
    private static boolean stop = false;

    public DelayedTyper(long delay, char c) {
        itsDelay = delay;
        itsChar = c;
    }

    @Override
    public void execute() {
        System.out.print(itsChar);
        if (!stop) {
            delayAndRepeat();
        }
    }

    private void delayAndRepeat() {
        engine.addCommand(new SleepCommand(itsDelay, engine, this));
    }

    public static void main(String args[]) throws Exception {
        engine.addCommand(new DelayedTyper(100, '1'));
        engine.addCommand(new DelayedTyper(300, '3'));
        engine.addCommand(new DelayedTyper(500, '5'));
        engine.addCommand(new DelayedTyper(700, '7'));

        Command stopCommand = new Command() {
            @Override
            public void execute() {
                stop = false;
            }
        };

        engine.addCommand(new SleepCommand(20000, engine, stopCommand));
        engine.run();
    }
}

3 运行结果

      下图这些字符串之所以有差别是因为CPU时钟和实时时钟没有完美的同步。这种不可确定的行为是多线程系统的特点。

135711131511317131151131713511113151713111351113171135111315713111135117131113511137115131113157
113111351171311513111357111311513117311513111713151131135117113151131171351113111357111311513171
315111311713511131517131113151311713511113157131111351137111135111371151311311517131113511713115
131113571131113511171311513117131513111135171311151317131151131171351131115317111351131171135111
31157131113511137115131113115713111315137111135111371153111

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值