在java并发包中有没有任何执行器可以确保所有任务都按照提交顺序完成?
问题描述:
从标题的想法演示一个代码示例:在java并发包中有没有任何执行器可以确保所有任务都按照提交顺序完成?
executor.submit(runnable1);
executor.submit(runnable2);
我需要确保runnable1将完成前runnable2开始,我还没有找到执行人文档中这样的行为的任何证据。
关于我正在解决的问题: 我需要将大量日志写入文件。每个日志需要很多预计算(格式化和其他一些东西)。所以,我想把每个日志记录任务放到一个队列中,并在一个单独的线程中处理这些任务。当然,保持日志排序非常重要。
答
单线程执行程序将按提交的顺序执行所有任务。如果您想要同时执行任务,则只能使用具有多个线程的线程池。
将任务添加到队列本身可能很昂贵。您可以使用队列或创建对象使用一个交换这样
该避免的。
速度更快的替代方法是使用不需要后台线程的内存映射文件(实际上操作系统在后台工作),这又快得多了。它支持每秒几微秒的延迟和数百万条消息。
答
您可以创建一个简单的包装像下面这样使你的所有的Runnable都在同一个线程(即顺序)执行,并提交包装执行人来代替。这并没有解决日志记录问题。
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);
答
假设你正在做一些日志文件的后分析?你有没有考虑过他们写的订单,以后再离线重新订购。您可以在提交时使用时间戳或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);
}
}