如何实现接收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,提问作者Олег Місько
相关产品推荐
相关产品推荐

