我必须多线程一个方法,该方法以 1000 的批次运行代码。我需要将这些批次分配给不同的线程。
目前我已经产生了 3 个线程,但所有 3 个线程都在挑选第一批 1000 个。我希望其他批次不应该选择同一批次,而是选择其他批次。
请帮助并提出建议。
我必须多线程一个方法,该方法以 1000 的批次运行代码。我需要将这些批次分配给不同的线程。
目前我已经产生了 3 个线程,但所有 3 个线程都在挑选第一批 1000 个。我希望其他批次不应该选择同一批次,而是选择其他批次。
请帮助并提出建议。
我会使用 ExecutorService
int numberOfTasks = ....
int batchSize = 1000;
ExecutorService es = Executors.newFixedThreadPool(3);
for (int i = 0; i < numberOfTasks; i += batchSize) {
final int start = i;
final int last = Math.min(i + batchSize, numberOfTasks);
es.submit(new Runnable() {
@Override
public void run() {
for (int j = start; j < last; j++)
System.out.println(j); // do something with j
}
});
}
es.shutdown();
您需要同步访问批处理中的作业列表。(“同步”本质上意味着“确保线程了解潜在的竞争条件”。在大多数情况下,这意味着“让某个方法一次由单个线程执行”。)
这是使用java.util.concurrent
包最容易解决的问题。看看BlockingQueue
例如ArrayBlockingQueue
或的各种实现LinkedBlockingQueue
。
将批次放入 aBlockingQueue
并让您的工作线程从队列中获取批次。
检索批次时使用 alock
或 a 。mutex
这样,线程就不能同时访问临界区,也不会意外访问同一个批次。
我假设你正在删除一个批次,一旦它被一个线程选中。
编辑:aioobe 和 jonas 的答案更好,使用它。这是一个替代方案。:)