适用于非线程安全代码的执行器
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
语义中抽象出您的业务逻辑是可行的方法。实施一个 Callable
或 Runnable
,您可以在不启动新的 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:
提供的单线程执行器
- 在将
Runnable
或 Callable
任务提交给 ExecutorService
之前线程中的操作 发生在 采取的任何操作之前通过该任务,
- 反过来 先于 结果通过
Future.get()
. 检索
因此,如果线程 运行 单元测试对所有提交的任务执行 Future.get()
,则对任何共享对象的所有更改都将安全发布,并且线程 运行 单元测试可以安全地检查那些共享对象。
我正在开发一些最终将成为多线程的代码,使用线程池 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
语义中抽象出您的业务逻辑是可行的方法。实施一个 Callable
或 Runnable
,您可以在不启动新的 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:
- 在将
Runnable
或Callable
任务提交给ExecutorService
之前线程中的操作 发生在 采取的任何操作之前通过该任务, - 反过来 先于 结果通过
Future.get()
. 检索
因此,如果线程 运行 单元测试对所有提交的任务执行 Future.get()
,则对任何共享对象的所有更改都将安全发布,并且线程 运行 单元测试可以安全地检查那些共享对象。