You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现接收Command接口对象并加锁串行执行任务的队列?

实现串行执行的Command队列

要实现一个能接收Command接口对象并串行、线程安全执行的队列,我们可以结合阻塞队列和专用工作线程来实现,既保证任务顺序,又能高效处理提交的命令。下面是完整的实现方案:

1. 定义Command接口(你提供的基础代码)

首先是核心的Command接口,所有可执行任务都要实现它:

public interface Command {
    void execute();
}

2. 实现BasicCommand示例类

这是一个简单的Command实现,用来测试队列功能:

import android.util.Log;

public class BasicCommand implements Command {
    private int operationId;

    public BasicCommand(int operationId) {
        this.operationId = operationId;
    }

    @Override
    public void execute() {
        Log.d("CommandQueue", "Executing operation: " + operationId);
        // 这里可以添加具体的业务逻辑,比如网络请求、数据库操作等
    }
}

3. 核心:线程安全的CommandQueue实现

这个队列类负责接收命令、存储命令,并保证串行执行。我们使用LinkedBlockingQueue(线程安全的阻塞队列)来存储待执行的命令,同时启动一个专用的工作线程循环取出命令执行:

import java.util.concurrent.LinkedBlockingQueue;

public class CommandQueue {
    // 线程安全的阻塞队列,存储待执行的Command
    private final LinkedBlockingQueue<Command> commandQueue = new LinkedBlockingQueue<>();
    // 工作线程,负责串行执行命令
    private final WorkerThread workerThread;

    public CommandQueue() {
        workerThread = new WorkerThread();
        // 设置为守护线程,避免影响应用退出
        workerThread.setDaemon(true);
        workerThread.start();
    }

    // 提交命令到队列
    public void submitCommand(Command command) {
        try {
            // 将命令加入队列,队列满时会阻塞(LinkedBlockingQueue默认容量是Integer.MAX_VALUE,一般不会满)
            commandQueue.put(command);
        } catch (InterruptedException e) {
            // 处理中断异常
            Thread.currentThread().interrupt();
            throw new RuntimeException("Failed to submit command", e);
        }
    }

    // 工作线程类,循环执行队列中的命令
    private class WorkerThread extends Thread {
        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    // 从队列取出命令,队列为空时会阻塞等待
                    Command command = commandQueue.take();
                    // 串行执行命令,单线程执行天然保证顺序,无需额外加锁
                    command.execute();
                } catch (InterruptedException e) {
                    // 线程被中断,退出循环
                    Thread.currentThread().interrupt();
                    break;
                } catch (Exception e) {
                    // 捕获Command执行时的异常,避免工作线程崩溃
                    Log.e("CommandQueue", "Error executing command", e);
                }
            }
        }
    }

    // 可选:停止工作线程(比如应用退出时调用)
    public void shutdown() {
        workerThread.interrupt();
    }
}

关键细节说明

  • 线程安全保证:LinkedBlockingQueue本身是线程安全的,put()和take()方法都由内部锁保证原子性,所以多线程提交命令也不会有问题。
  • 串行执行:所有命令都由同一个WorkerThread执行,天然保证串行顺序,完全符合你要求的“执行时加锁保证顺序”(单线程执行本身就是最可靠的串行方式)。
  • 阻塞等待:当队列空时,take()方法会阻塞工作线程,避免空循环浪费资源;当队列满时,put()方法会阻塞提交线程(不过默认容量极大,一般不会触发)。
  • 异常处理:在工作线程中捕获execute()抛出的异常,避免单个命令执行失败导致整个队列停止工作。

使用示例

// 创建队列实例
CommandQueue queue = new CommandQueue();

// 提交多个命令(可以在任意线程提交)
queue.submitCommand(new BasicCommand(1));
queue.submitCommand(new BasicCommand(2));
queue.submitCommand(new BasicCommand(3));

// 当不需要队列时,调用shutdown停止工作线程
// queue.shutdown();

这样实现的队列完全满足你的需求:接收Command对象,串行、线程安全地执行每个命令的任务。

内容的提问来源于stack exchange,提问作者Олег Місько

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:28:12