表的总和与螺纹

时间:2016-03-17 18:34:04

标签: java multithreading

我正在尝试用线程对表进行求和。我正在创建一个具有给定长度的表,然后尝试使用给定的线程名称创建一个总和。

根据他的说法,每个帖子都占据了一席之地。

例如:

3个线程上包含12个元素的表:

0线程采用[0,3,6,9]元素

1个线程采用[1,4,7,10]元素

2个线程采用[2,5,8,11]元素

线程将这些数字相加,然后返回结果。在它之后,我将它们总结在一起,并获得结果。

这是我的单个Callable对象实现:

public class TableSumThread implements Callable<Integer> {

private int indeks;
private int[] table;

public TableSumThread(int indeks, int[] table) {
    this.indeks = indeks;
    this.table = table;
}


@Override
public Integer call() throws Exception {
    int iter = indeks;
    int sum = 0;
    while(iter < table.length) {
        sum += table[iter];
        iter += indeks;
    }
    return sum;
}

}

这是我的“执行官”:

public class TableSumExecutor {
private int[] table;
private int executors;

public Integer execute() {
    ExecutorService executorService = Executors.newFixedThreadPool(executors);
    List<Future<Integer>> results = new ArrayList<Future<Integer>>(executors);

    for (int i = 0; i < executors; i++) {
        Callable<Integer> task = new TableSumThread(i, table);
        results.add(executorService.submit(task));
    }
    System.out.println("After creating all threads.");
    int suma = sum(results);
    return suma;
}

private int sum(List<Future<Integer>> results) {
    int sum = 0;
    for (int i = 0; i < results.size(); i++) {
        try {
            sum += results.get(i).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
    return sum;
}

主:

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    System.out.println("Table length: ");
    int nTable = scanner.nextInt();
    System.out.println("Threads number: ");
    int nThreads = scanner.nextInt();

    Random random = new Random();
    int[] tablica = new int[nTable];
    for (int i = 0 ; i < tablica.length ; i++)
        tablica[i] = Math.abs(random.nextInt() % 9 + 1);

    TableSumExecutor tableSumExecutor = new TableSumExecutor(tablica, nThreads);
    int result = tableSumExecutor.execute();

    System.out.println("And the result is: " + result);
}

一切都很好,线程执行所有任务,但程序阻塞:

sum += results.get(i).get();

我没有得到任何例外,它只是阻止。我也在调试器上检查它。所有任务都完成了,结果等待最后一步。

我可能没有正确使用Future类型的get()?

EDIT。 好的,我解决了一个问题。但程序毕竟没有结束。当我在main executorService.isShutdown()中显示结果后进行检查时,它是错误的。我应该手动终止所有线程,还是应该自动终止?

1 个答案:

答案 0 :(得分:1)

在这行代码中:

Callable<Integer> task = new TableSumThread(i, table);

在for循环的第一次迭代中,&#34; i&#34;因此,您使用indeks = 0创建TableSumThread对象。所以在此循环中:

int iter = indeks;
int sum = 0;
while(iter < table.length) {
    sum += table[iter];
    iter += indeks;
}

你没有增加它的变量,这是无限循环。 这就是你的第一个线程永远不会结束并阻止主线程执行的原因(因为未来对象上的get()是阻塞操作)。您可以尝试传递两个变量 - 开始索引和迭代(在您的情况下 - 常量3)。像新的TableSumThread(i,3,表)。 希望这会有所帮助。