2017-04-07 186 views
2

我想以序列化方式运行一些任务。对此的典型解决方案是创建一个Java:另一个多线程执行程序中的单线程子执行程序

Executor executor = Executors.newSingleThreadedExecutor(); 

并运行此任务上的任务。

但是,我已经有了一个多线程的线程池。

有没有一种简单的方法来派生一个行为像单线程的子执行器(如:一次只运行一个任务),但是使用另一个(可能是非单线程)执行器作为“后端”而不是创建一个全新的操作系统线程?

有几个用例为什么我们会想这样做:

  • 的应用程序可能已经有了例如线程池后台任务, 设置优先级等,我们希望重用。
  • 类似地,我们可能会传递一个执行程序,它不只是一个普通的线程池(例如推迟执行购买,测量执行时间等)
    • 其中在MoreExecutors.directExecutor)使(为一个子集测试(以便例如期货立即解决)。

编辑:加入上面的例子

+2

你可以把你想要在单线程中运行的任务代码?我认为在单线程中运行任务将由任务本身决定。如果您不想在另一个线程的任务内执行任何操作,它只会在同一个线程中运行。 –

+0

我同意Vijendra - 你的问题很有趣,但为了给予更多有用的反馈,一些代码可能会帮助我们。 – GhostCat

回答

2

这样一个零线程执行程序被称为SerialExecutor,在java文档中描述为java.util.concurrent.Executor。但是它有一点缺点:对于每个提交的Runnable,它都会创建一个包装对象。 My own implementation不会创建其他对象。

+0

很酷,谢谢!虽然他们会在java _docs_中放置一个有用的类,而不是实际的代码,但有些令人惊讶,我不知道它从那里复制了多少次。 – Latanius

0

我的建议:不要去那里。

从实际的角度来看,这并没有多大意义:你愿意为一个问题引入一个更复杂的解决方案......这不是一个真正的问题。

你会看到:当那个“其他”多线程服务空闲时......为什么要把它放在第一位呢?如果你想保存OS线程;为什么你使用那种似乎厌倦缺乏工作的多线程服务?

但是,如果它不是闲置 - 您认为您可以从该“单线程”服务“分阶段”完成任务吗?以一致的方式?

是的,线程并不是很便宜;但是当你确实在保存单个线程为你解决问题的时候......回去一个段落并再次问自己:那个闲置的多线程服务呢?

所以,也许有一种技术方法来实现你的想法;不过实话说;我的答案是 - 坚持你已经有了:

Executor executor = Executors.newSingleThreadedExecutor(); 

并增加对其他答案/评论:是角色模型可以帮助这里;但混淆概念很少是一个好主意。如果Actor方法很好地适合你的整体模型(也许有很好的方法来改变你的代码的更多部分来利用它) - 很好。但是,如果没有;要小心增加额外的概念复杂性只是为了解决一个问题......正如所说的那样;首先可能不是真正的问题。

+0

starter需要的主题实际上是一个Actor,它接受类型为Runnable的消息并通过调用message.run()来处理它们。 Actor的概念并不复杂,足够直观,并且在过去的40年里得到了成功的开发。详情请参阅https://github.com/rfqu/CodeSamples/tree/master/src/simpleactor –

+0

我喜欢你的简短回答;从而提高了;但经过一段时间的思考后,我决定保留我的答案。一切都取决于OP真正具有的“多大的问题”。我们不做事,因为我们可以,但是因为它们有意义并且改进了一些值得改进的东西。而且这个解决方案今天在两个池中运行;通过重新使用一个泳池来取得什么成果? (可能很多,但这实际上取决于他在做什么,以及发生的规模)。 – GhostCat

+0

感谢您的回答!我确实同意,对于大多数情况来说,这可能是个好主意,操作系统线程毕竟不是那么昂贵。但是,如果可能有用,可能会出现更多奇怪的情况;看到我上面添加的例子。 – Latanius