从标题中演示该想法的代码示例:
executor.submit(runnable1);
executor.submit(runnable2);
我需要确保runnable1将在runnable2启动之前完成,而我在执行程序文档中没有找到任何此类行为的证据。
关于我正在解决的问题: 我需要在文件中写入大量日志。每个日志都需要大量预先计算(格式化和其他一些东西)。所以,我想将每个日志记录任务放到一种队列中,并在一个单独的线程中处理这些任务。当然,保持日志订购非常重要。
答案 0 :(得分:4)
单线程执行程序将按提交的顺序执行所有任务。如果您希望同时执行任务,则只能使用具有多个线程的线程池。
将任务添加到队列本身可能很昂贵。您可以使用像这样的交换器
这可以避免使用队列或创建对象。
更快的替代方法是使用不需要后台线程的内存映射文件(实际上操作系统在后台工作)这再次快得多。它支持亚微秒延迟和每秒数百万条消息。
答案 1 :(得分:0)
您可以创建一个类似下面的简单包装器,以便所有Runnables在同一个线程中执行(即按顺序执行),然后将该包装器提交给执行程序。这并不能解决日志记录问题。
class MyRunnable implements Runnable {
private List<Runnable> runnables = new ArrayList<>();
public void add(Runnable r) {
runnables.add(r);
}
@Override
public void run() {
for (Runnable r : runnables) {
r.run();
}
}
}
//......
MyRunnable r = new MyRunnable();
r.add(runnable1);
r.add(runnable2);
executor.submit(r);
答案 2 :(得分:0)
据推测,您正在对日志文件进行一些后期分析?您是否考虑过不关心他们写的订单以及稍后离线重新订购。您可以在提交时使用时间戳或AtomicLong分配唯一ID吗?
代码草图(未经测试)看起来像这样:
import java.util.concurrent.atomic.AtomicLong;
class MyProcessor {
public void work()
for (Object data: allData) {
executor.submit(new MySequencedRunnable(data);
}
}
}
class MySequencedRunnable implements Runnable {
private static final AtomicLong LOG_SEQUENCE_ID = new AtomicLong(0);
private final Object data;
MySequencedRunnable(Object data) {
this.data = data;
}
public void run() {
LOGGER.log(LOG_SEQUENCE_ID.incrementAndGet(), data);
}
}