![](/img/trans.png)
[英]How to make executerService.shutdown wait for nested threads invokation
[英]How can I divide into threads using ExecuterService?
我有一个包含约5000个对象的数组。 对于每个对象,我计划执行一些逻辑。 每个对象的逻辑相同。 我想尽我所能,所以我来到了ExecutorService,它位于java.util.cuncurrent中。 我决定在一个线程中处理100个对象,因此我将总数(〜5k)分为间隔
private List<Integer> divideIntoIntervals(Integer total)
{
List<Integer> intervals = new ArrayList<Integer>();
intervals.add(0);
int n = total / PART_SIZE;
int leftover = total % PART_SIZE;
if(n!=0)
{
intervals.add(PART_SIZE);
for (int i=2; i<=n; i++)
{
intervals.add(PART_SIZE*i);
}
intervals.add(PART_SIZE*n+leftover);
}
return intervals;
}
因此,该数组将是:0、100、200、300,...,5000、5041。您会建议使用哪种当前列表? 我正计划创建逻辑,该逻辑在另一个间隔内寻找我的cuncurrent数组。
您可能不需要并发列表。 只要您在线程执行工作时不修改列表,就可以创建一个单独的可运行在其自身范围内的Runnable
,并将这些可运行对象提交给具有适当线程数(在您的情况下为ThreadPoolExecutorService
。 。 任务将自动在线程之间平均分配:
ExecutorService executor = Executors.newFixedThreadPool(list.size() / 100 + 1);
// (+1 in case there are less than 100 items)
for (int i = 0; i < list.size(); i += 100) {
final int start = i;
executor.execute(() -> {
int end = start + 100;
if (end > list.size()) {
end = list.size();
}
for (int j = start; j < end; ++j) {
list.get(j).doYourLogicHere();
}
});
}
如果您不确定是否要在这些任务之外修改列表,则应根据要处理的修改内容更改代码。 例如,如果可以在处理过程中将新项目添加到列表中,并且您不在乎在此阶段是否处理这些新项目,那么您可能希望使用CopyOnWriteArrayList
并将上面的内部循环更改为使用迭代器而不是基于int的索引。 这将导致代码使用创建迭代器时所用列表的快照(并且如果您在进行迭代时未进行任何修改,则不会进行任何实际复制)。 根据追加新项目的时间,此快照可能包括也可能不包括这些快照,但是至少它是一致的,没有中断。
您也可以使用newCachedThreadPool
方法。 这将创建一个线程池,该线程池会根据需要创建新线程,但是将在先前构造的线程可用时重用它们。 资源
我如何使用它的示例:
// Create an executor service with a thread pool that creates new threads as needed,
// but will reuse previously constructed threads when they are available
ExecutorService executorService = Executors.newCachedThreadPool();
Integer finalMinValue = minValue;
Integer finalMaxValue = maxValue;
executorService.execute(() -> {
// Initialise buckets
int bucketCount = (finalMaxValue - finalMinValue) / bucketSize + 1;
List<List<Integer>> buckets = new ArrayList<>(bucketCount);
for (int i = 0; i < bucketCount; i++) {
buckets.add(new ArrayList<>());
}
// Distribute input array values into buckets
for (Integer anArrayElement : arrayToSort) {
buckets.get((anArrayElement - finalMinValue) / bucketSize).add(anArrayElement);
}
// Sort buckets and place back into input array
// Loop through the contents of each bucket
for (List<Integer> bucket : buckets) {
Integer[] bucketArray = new Integer[bucket.size()];
bucketArray = bucket.toArray(bucketArray);
InsertionSort.sort(bucketArray);
for (Integer aBucketArray : bucketArray) {
arrayToSort[currentIndex] = aBucketArray;
incrementSync();
}
}
});
在Github上可以找到有关此实现的更多信息
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.