java并发包中是否有任何执行器可以保证所有任务都按照提交的顺序完成?
用于演示标题中的想法的代码示例:
executor.submit(runnable1);
executor.submit(runnable2);
我需要确保 runnable1 将在 runnable2 启动之前完成,并且我在执行程序文档中没有找到此类行为的任何证据。
关于我正在解决的问题: 我需要将大量日志写入文件。每个日志都需要大量的预计算(格式化和其他一些东西)。因此,我想将每个日志记录任务放入一种队列中,并在单独的线程中处理这些任务。当然,保持日志有序也很重要。
A code sample for demonstration of the idea from the title:
executor.submit(runnable1);
executor.submit(runnable2);
I need to be sure that runnable1 will finish before runnable2 start and I haven't found any proofs of such behavior in the executors documentation.
About the problem I'm solving:
I need write lots of logs to a file. Each log requires much precomputing (formatting and some other stuff). So, I want to put each logging task to a kind of queue and process these tasks in a separate thread. And, of course, it's important to keep logs ordering.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
单线程执行器将按照提交的顺序执行所有任务。如果您希望同时执行任务,则只能使用具有多个线程的线程池。
将任务添加到队列本身的成本就很高。您可以使用这样的 Exchanger
http://vanillajava.blogspot.com/2011/09/exchange-and-gc-less-java.html?z#!/2011/09/exchange-and-gc-less-java。 html
这避免使用队列或创建对象。
另一种更快的替代方法是使用不需要后台线程的内存映射文件(实际上操作系统在后台工作),这又快得多。它支持亚微秒延迟和每秒数百万条消息。
https://github.com/peter-lawrey/Java-Chronicle
A single threaded executor will perform all tasks in the order submitted. You would only use a thread pool with multiple threads if you wanted the tasks to be perform concurrently.
Adding tasks to a queue can be expensive in itself. You can use an Exchanger like this
http://vanillajava.blogspot.com/2011/09/exchange-and-gc-less-java.html?z#!/2011/09/exchange-and-gc-less-java.html
This avoid using a queue or creating object.
An alternative which is faster is to use a memory mapped file which doesn't require a background thread (actually the OS is working in the background) This is much faster again. It supports sub-microsecond latencies and millions of messages per second.
https://github.com/peter-lawrey/Java-Chronicle
您可以创建一个像下面这样的简单包装器,以便所有 Runnables 都在同一线程中执行(即顺序执行),然后将该包装器提交给执行器。这并没有解决日志记录问题。
You could create a simple wrapper like the one below so that all your Runnables are executed in the same thread (i.e. sequentially), and submit that wrapper to the executor instead. That does not address the logging issue.
想必您正在对日志文件进行一些后期分析?您是否考虑过不关心它们的编写顺序并稍后离线重新排序。您可以在提交时使用时间戳或 AtomicLong 分配唯一的 id?
代码草图(未经测试)如下所示:
}
另请考虑,如果您使用的是 log4j 之类的东西,请使用 NDC 或 MDC 协助重新订购。
Presumably you are doing some post-analysis of the logfile? Have you considered not caring about the order they're written and re-ordering offline later. You could allocate a unique id at submit time using, a timestamp or AtomicLong?
a code sketch (untested) would look like this:
}
Also consider, if you're using something like log4j, using NDC or MDC to assist with the re-ordering.