当前位置: 代码迷 >> java >> ExecutorService 性能问题
  详细解决方案

ExecutorService 性能问题

热度:23   发布时间:2023-07-25 19:25:46.0

我一直在尝试使用 Executor Service 在我的 PC 内核之间并行运行多个任务,到目前为止,Windows 资源管理器告诉我我正在使用 100% 的 CPU(顺便说一句,4 个内核),但几乎没有改进顺序方法。 这是我正在使用的代码。

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class NNTEST implements Callable<Object> throws Exception {

public long id;
public int m = 1000000000;
public double average;
public Random semilla = new Random();

public NNTEST(long sem) {
    this.id = sem;
    semilla.setSeed(sem);
}

@Override
public Object call() throws Exception {
    return doComputation();
}

public double doComputation() {
    for (int j = 0; j < m; j++) {
        average = average + semilla.nextInt();
    }
    average = average / m;
    return average;
}

public static void main(String[] args) {
    ExecutorService es = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
    List<Callable<Object>> list = new ArrayList<>(4);

    for (int i = 0; i < 4; i++) {
        NNTEST tes = new NNTEST(i);
        list.add(tes);
    }

    try {
        long t = System.currentTimeMillis();
        List<Future<Object>> lista = es.invokeAll(list);

        System.out.println("Multi-Threaded lasted: " + (System.currentTimeMillis() - t));
        es.shutdown();
    } catch (Exception e) {
        System.out.println(e);
    }

    long t1 = System.currentTimeMillis();
    for (int j = 0; j < 4; j++) {
        NNTEST ts = new NNTEST(j);
        ts.call();
    }
    System.out.println("Sequential lasted: " + (System.currentTimeMillis() - t1));
}
}

上面的代码输出这个:

Multi-Threaded lasted: 56104
Sequential lasted: 52616

完成一次对 NNTEST 的调用大约需要 12 秒,这在顺序模式下是一致的 (12*4)=52.6 秒完成 4 次运行。 但是我的问题是 Executor Service,因为我的 PC 有 4 个内核,如果每个内核处理一个线程,它不应该在大约 12 秒内完成 4 次运行,因为每个内核都在执行 NNTEST 的独立任务吗? 有什么我想念的吗?

PD:我已经研究了这个线程(双关语),因为它们似乎有类似的问题,但我为 NNTEST 的每个对象使用了 Random。

谢谢你。

我对此知之甚少..但据我所知..您正在使用公共双平均值,这是全局变量,并且您一次又一次地对其进行变异,如果您正在更改变量的状态,则并行方法效果不佳。 .try 在将doComputaion 方法转换为Pure Function 之后。 .观看这个关于异步编程和Venket Subramanium的java Streams的视频..你会得到很多澄清 ..我试过了,但我没有得到太多,因为我只是一个java新鲜..