我正在嘗試總結一個帶有線程的表。我創建一個給定長度的表,然後嘗試創建一個給定名稱的線程總和。與線程表的總和
根據他的indeah,每個線程都佔據了表的一部分。
例如:
表與3個線程12個元素:
0線程取[0,3,6,9]元素
1線程取[1,4,7, 10]元素
2螺紋服用[2,5,8,11]元素
線程被求和該數然後返回結果。之後,我將它們彙總在一起,並獲得結果。
這是我的一個可調用對象實現:
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()嗎?
編輯。 好的,我解決了一個問題。但是程序畢竟還沒有結束。當我在主executorService.isShutdown()中顯示結果後檢查它是錯誤的。我應該終止所有線程manualy,或者它應該自動終止?
Re,「你可能會發現一些設計錯誤嗎?」比較好的名字,例如:名爲'TableSumThread'的類沒有實現線程。它實現了_task_。任務是代表某件工作需要完成的對象。 _thread_是一個執行代碼的深魔法系統對象,還有一個'ExecutorService'(a.k.a.,_thread pool_)是一個使用一個或多個線程來執行_perform_任務的對象。 –
......而你的'TableSumExecutor'類不是'Executor':這是一個商業邏輯的東西,它使用了一個'ExecutorService'。我會給它一個名稱,說明它的作用(例如,「TableSummer」)。 –
您的程序可能需要更多的時間才能運行,而不是在一個線程中完成所有操作。創建線程需要時間,同步線程需要時間。我不知道在使用多個線程獲得優勢之前數組的大小有多大,但我猜測的是數以萬計的數組元素。 (在實驗中使用你的程序很容易找到答案。) –