适用于非线程安全代码的执行器

Executor suitable for non thread-safe code

我正在开发一些最终将成为多线程的代码,使用线程池 Executor。线程池执行的任务将进行回调并(有时)将进一步的任务提交到任务队列。我想先开发单线程代码,把它做好(我正在使用测试驱动开发)然后才进行更改以确保线程安全(锁等)。为此,我需要一个可以安全地用于非线程安全代码的 Executor

认为 这意味着我需要一个 Executor 是单线程的。也就是说,它导致所有工作都由调用线程完成。 JRE 是否提供这样的Executor?或者是否可以将其 Executor 之一配置为在该模式下运行?


我已经在使用 Humble Object testing pattern to test most of my code single-threaded. However, some of my code must interact with an Executor, or perhaps an ExecutorService, because it is about scheduling 和重新提交任务,它将以一种非常重要的方式进行。测试 那个 代码是这里的挑战。这些任务更新一个共享对象,该对象保存它们的结果和输入数据。我想推迟必须使该共享对象线程安全,直到我实现并调试了调度和重新提交代码。

如果您计划首先开发单线程解决方案,那么从 Thread 语义中抽象出您的业务逻辑是可行的方法。实施一个 CallableRunnable,您可以在不启动新的 Thread 的情况下进行测试,例如通过在单元测试中使用模拟 Executor

如果代码确实需要 Executor, and not a (much more complex) ExecutorService,则很容易实现您自己的单线程执行器,它可以精确地完成所需的工作。 Executor 的 API 文档甚至向您展示了如何这样做:

class DirectExecutor implements Executor {
   public void execute(Runnable r) {
     r.run();
   }
}

如果代码确实需要 ExecutorService可能 Executors.newSingleThreadExecutor() is adequate for testing the non thread-safe code, despite the resulting program having two threads (the thread running the unit tests and the single thread-pool thread of the ExecutorService). This is because an ExecutorService must provide the following thread-safety guarantees:

提供的单线程执行器
  • 在将 RunnableCallable 任务提交给 ExecutorService 之前线程中的操作 发生在 采取的任何操作之前通过该任务,
  • 反过来 先于 结果通过 Future.get().
  • 检索

因此,如果线程 运行 单元测试对所有提交的任务执行 Future.get(),则对任何共享对象的所有更改都将安全发布,并且线程 运行 单元测试可以安全地检查那些共享对象。