MultiThread Java仅使用一个线程

时间:2013-09-08 10:05:58

标签: java multithreading executorservice callable

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

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%,这只是一个线程...想法的人?

由于

3 个答案:

答案 0 :(得分: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对象。

答案 1 :(得分: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;
}

答案 2 :(得分: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
}