gpt4 book ai didi

Java加速进程/线程

转载 作者:行者123 更新时间:2023-11-29 04:14:04 25 4
gpt4 key购买 nike

我有一个相当大的 ArrayList。

我必须遍历每个索引,并进行昂贵的计算

我第一个加速它的想法是把它放到一个线程中。它有效,但它仍然非常慢。我修改了计算,以降低成本,但它仍然很慢。我想到的最好的解决方案基本上就是这个。

public void calculate(){
calculatePart(0);
calculatePart(1);
}

public void calculatePart(int offset) {
new Thread() {
@Override
public void run() {
int i = offset;
while(arrayList.size() > i) {
//Do the calulation
i +=2;
}
}
}.start();
}

但这感觉像是一个懒惰的、不专业的解决方案。这就是为什么我要问是否有更清洁甚至更快的解决方案

最佳答案

假设在每个元素上执行任务不会导致数据竞争,您可以利用并行的力量。为了最大化同时发生的计算数量,您必须将任务分配给系统中可用的每个处理器。

在 Java 中,您可以获得可用的处理器(内核)数量:

int parallelism = Runtime.getRuntime().availableProcessors();

想法是创建与可用处理器数量相等的线程。

因此,如果您有 4 个处理器可用,您可以创建 4 个线程并要求它们以 4 的间隔处理项目。假设您有一个大小为 10 的列表,需要并行处理。

然后,

线程 1 处理索引 0,4,8 处的项目
线程 2 处理索引 1、5、9 处的项目
线程 3 处理索引 2,6 处的项目
线程 4 处理索引 3,7 处的项目

我尝试使用以下代码模拟您的场景:

import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class SpeedUpTest {

public static void main(String[] args) throws InterruptedException, ExecutionException {
long seqTime, twoThreadTime, multiThreadTime;
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

long time = System.currentTimeMillis();
sequentialProcessing(list);
seqTime = System.currentTimeMillis() - time;

int parallelism = 2;
ExecutorService executorService = Executors.newFixedThreadPool(parallelism);
time = System.currentTimeMillis();
List<Future> tasks = new ArrayList<>();
for (int offset = 0; offset < parallelism; offset++) {

int finalParallelism = parallelism;
int finalOffset = offset;
Future task = executorService.submit(() -> {
int i = finalOffset;
while (list.size() > i) {
try {
processItem(list.get(i));
} catch (InterruptedException e) {
e.printStackTrace();
}
i += finalParallelism;
}
});
tasks.add(task);
}
for (Future task : tasks) {
task.get();
}
twoThreadTime = System.currentTimeMillis() - time;

parallelism = Runtime.getRuntime().availableProcessors();
executorService = Executors.newFixedThreadPool(parallelism);
tasks = new ArrayList<>();
time = System.currentTimeMillis();
for (int offset = 0; offset < parallelism; offset++) {

int finalParallelism = parallelism;
int finalOffset = offset;
Future task = executorService.submit(() -> {
int i = finalOffset;
while (list.size() > i) {
try {
processItem(list.get(i));
} catch (InterruptedException e) {
e.printStackTrace();
}
i += finalParallelism;
}
});
tasks.add(task);
}
for (Future task : tasks) {
task.get();
}
multiThreadTime = System.currentTimeMillis() - time;
log("RESULTS:");
log("Total time for sequential execution : " + seqTime / 1000.0 + " seconds");
log("Total time for execution with 2 threads: " + twoThreadTime / 1000.0 + " seconds");
log("Total time for execution with " + parallelism + " threads: " + multiThreadTime / 1000.0 + " seconds");


}

private static void log(String msg) {
System.out.println(msg);
}

private static void processItem(int index) throws InterruptedException {
Thread.sleep(5000);
}

private static void sequentialProcessing(List<Integer> list) throws InterruptedException {

for (int i = 0; i < list.size(); i++) {
processItem(list.get(i));
}
}

}

输出:

RESULTS:

Total time for sequential execution : 50.001 seconds

Total time for execution with 2 threads: 25.102 seconds

Total time for execution with 4 threads: 15.002 seconds

关于Java加速进程/线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53448577/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com