【发布时间】:2011-11-01 12:39:57
【问题描述】:
我必须对一个批量运行代码的方法进行多线程 1000 。我需要将这些批次分配给不同的线程。
目前我已经产生了 3 个线程,但所有 3 个线程都在挑选第一批 1000 个。 我希望其他批次不应该选择同一批次,而是选择其他批次。
请帮助并提出建议。
【问题讨论】:
-
能否请您出示SSCCE?
标签: java multithreading synchronize
我必须对一个批量运行代码的方法进行多线程 1000 。我需要将这些批次分配给不同的线程。
目前我已经产生了 3 个线程,但所有 3 个线程都在挑选第一批 1000 个。 我希望其他批次不应该选择同一批次,而是选择其他批次。
请帮助并提出建议。
【问题讨论】:
标签: java multithreading synchronize
我会使用 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();
【讨论】:
将批次放入BlockingQueue 并让您的工作线程从队列中取出批次。
【讨论】:
检索批次时使用lock 或mutex。这样,线程就不能同时访问临界区,也不会意外访问同一个批次。
我假设您正在删除一个批次,一旦它被线程拾取。
编辑:aioobe 和 jonas 的答案更好,使用它。这是一个替代方案。 :)
【讨论】:
您需要同步访问批处理中的作业列表。 (“同步”本质上意味着“确保线程了解潜在的竞争条件”。在大多数情况下,这意味着“让某个方法一次由单个线程执行”。)
使用java.util.concurrent 包最容易解决这个问题。查看BlockingQueue 的各种实现,例如ArrayBlockingQueue 或LinkedBlockingQueue。
【讨论】: