0

我正在做这个项目,我想在我的代码中使用多线程。所以我开发了这段小代码并对其进行了测试,但结果发现它只使用了我计算机中的一个线程。有人可以告诉我它有什么问题以及如何改进它吗?

public static int choiceCount(List<Character> charlist) throws InterruptedException, ExecutionException {

    int coreCount = 8;
    ExecutorService e1 = Executors.newFixedThreadPool(coreCount);
    Integer total = 0;
    for (int i = 0; i < coreCount; i++) {
        Future<Integer> result = e1.submit(new Count(coreCount, i, charlist));
        total += result.get();
    }
    e1.shutdown();
    return total;
}

这是可调用的

class Count implements Callable<Integer> {
//where the processing code is
}

所以当我运行这个程序时,它只使用了我的 CPU 的 12.5%,这只是一个线程......想法伙计们?

谢谢

4

3 回答 3

3

问题出在你的循环中:

for (int i = 0; i < coreCount; i++) {
    Future<Integer> result = e1.submit(new Count(coreCount, i, charlist));
    total += result.get();
}

它的作用是:

  • 提交计算
  • 调用对象,get()等待计算完成Future
  • 然后进行循环的下一次迭代

因此,在每次迭代中,您的代码都在等待计算完成,然后再提交下一个迭代。

您应该创建两个循环,一个用于提交计算,它将所有Future对象存储在一个集合中,然后另一个循环调用get()每个Future对象。

于 2013-09-08T10:10:44.567 回答
1

您必须保存 Future 对象,而不是在提交下一个之前等待每个对象。

public static int choiceCount(List<Character> charlist) throws InterruptedException, ExecutionException {

    int coreCount = Runtime.getRuntime().availableProcessors();
    ExecutorService e1 = Executors.newFixedThreadPool(coreCount);
    int total = 0;
    List<Future<Integer>> futures = new ArrayList<>();
    // start all the tasks, before
    for (int i = 0; i < coreCount; i++) 
        futures.add(e1.submit(new Count(coreCount, i, charlist)));
    // notify the executor to stop when finished in case get() throws an exception
    e1.shutdown(); 
    // collecting the results.
    for (Future<Integer> future: futures)
        total += future.get();
    return total;
}
于 2013-09-08T13:58:33.237 回答
0

您应该创建一个列表,List<Callable<Integer>>然后invokeAll在将启动所有计算线程的执行程序上使用。

List<Callable<Integer>> callables = new ArrayList<Callable<Integer>>();
for (int i = 0; i < coreCount; i++) {
    callables.add(new Count(coreCount, i, charlist));
}
List<Future<Integer>> futures = executor.invokeAll(callables); //why is it e1?
//Then you can wait for all computations to  finish by calling
for (Future<Integer> future : futures) {
    Integer result = future.get(); //blocks for computation to finish.
    //do something with result
}
于 2013-09-08T10:20:34.640 回答