Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用ExecuterService划分线程?_Java_Multithreading_Java.util.concurrent - Fatal编程技术网

Java 如何使用ExecuterService划分线程?

Java 如何使用ExecuterService划分线程?,java,multithreading,java.util.concurrent,Java,Multithreading,Java.util.concurrent,我有一个数组,它有大约5000个对象。对于每个对象,我计划执行一些逻辑。每个对象的逻辑都是相同的。我想尽快完成它,所以我来到了ExecutorService,它位于java.util.current中。我决定在一个线程中处理100个对象,所以我将总数(~5k)划分为若干个区间 private List<Integer> divideIntoIntervals(Integer total) { List<Integer> intervals = new ArrayL

我有一个数组,它有大约5000个对象。对于每个对象,我计划执行一些逻辑。每个对象的逻辑都是相同的。我想尽快完成它,所以我来到了ExecutorService,它位于java.util.current中。我决定在一个线程中处理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;
}
private List divideintoInterval(整数总计)
{
列表间隔=新建ArrayList();
间隔。添加(0);
int n=总尺寸/零件尺寸;
int剩余=零件尺寸的总百分比;
如果(n!=0)
{
间隔。添加(零件尺寸);

对于(int i=2;i您可能不需要并发列表。只要您在线程工作时不修改列表,您就可以创建一个单独的
Runnable
,它在自己的范围内工作,并将这些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();
        }
    });
}
ExecutorService executor=Executors.newFixedThreadPool(list.size()/100+1);
//(+1,如果少于100项)
对于(int i=0;i{
int end=开始+100;
if(end>list.size()){
end=list.size();
}
对于(int j=开始;j<结束;++j){
list.get(j.doYourLogicHere();
}
});
}

如果您不能绝对确定不会在这些任务之外修改列表,则应根据您希望处理这些修改的方式来更改代码。例如,如果在处理过程中可以将新项目追加到列表中,并且您不关心在此阶段是否处理了这些新项目,然后,您可能希望使用
CopyOnWriteArrayList
,并将上面的内部循环更改为使用迭代器而不是基于int的索引。这将导致代码使用在创建迭代器时拍摄的列表快照(如果在迭代时没有修改,则不会进行任何实际复制)。根据附加新项目的时间,此快照可能包括也可能不包括这些项目,但至少它是一致的,不会有任何中断。

您可能不需要并发列表。只要在线程执行工作时不修改列表,您就可以创建一个单独的
可运行的
,在其自身范围内运行d将这些可运行程序提交到具有适当线程数的
ThreadPoolExecutorService
(在您的情况下约为50个线程)。任务将自动在线程之间均匀分布:

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();
        }
    });
}
ExecutorService executor=Executors.newFixedThreadPool(list.size()/100+1);
//(+1,如果少于100项)
对于(int i=0;i{
int end=开始+100;
if(end>list.size()){
end=list.size();
}
对于(int j=开始;j<结束;++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();
                }
            }
        });
//使用线程池创建执行器服务,该线程池根据需要创建新线程,
//但是,当以前构造的线程可用时,它们会重用吗
ExecutorService ExecutorService=Executors.newCachedThreadPool();
整数finalInvalue=minValue;
整数finalMaxValue=maxValue;
executorService.execute(()->{
//初始化存储桶
整数bucketCount=(finalMaxValue-finalInvalue)/bucketSize+1;
列表存储桶=新的ArrayList(bucketCount);
对于(int i=0;i

有关此实现的更多信息,请访问您也可以使用
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();
                }
            }
        });
//创建