我正在尝试用线程对表进行求和。我正在创建一个具有给定长度的表,然后尝试使用给定的线程名称创建一个总和。
根据他的说法,每个帖子都占据了一席之地。
例如:
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()中显示结果后进行检查时,它是错误的。我应该手动终止所有线程,还是应该自动终止?
答案 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,表)。 希望这会有所帮助。