我撰寫了以下代碼以計算 a 的哈希值String(基于 SHA-256),然后將所有輸出插入到 a 中ArrayList<String>:
ArrayList<Thread> threadList = new ArrayList<Thread>();
ArrayList<String> threadListStr = new ArrayList<String>();
int threadNumber = 100;
for (int i = 0; i < threadNumber; i ) {
String tId = String.valueOf(i);
Thread thr = new Thread(() -> {
threadListStr.add(calculateHash(tId));
});
threadList.add(thr);
}
// START the threads
for (int i = 0; i < threadNumber; i ) {
threadList.get(i).start();
}
// STOP the threads
for (int i = 0; i < threadNumber; i ) {
threadList.get(i).interrupt();
}
System.out.println("Size of ArrayList<String> is: " threadListStr.size());
System.out.println("Size of ArrayList<Thread> is: " threadList.size());
/////////////////////
public static String calculateHash(String tId) {
String tIdStr = org.apache.commons.codec.digest.DigestUtils.sha256Hex(tId);
return tIdStr;
}
但是,ArrayList 并沒有變得完整,正如您在運行 5 次代碼后看到的那樣,每次 ArrayList 都有不同的大小(盡管 ArrayList threadList 始終是完整的,因為執行緒數為 100。)
//1th run
Size of ArrayList<String> is: 60
Size of ArrayList<Thread> is: 100
//2nd run
Size of ArrayList<String> is: 30
Size of ArrayList<Thread> is: 100
//3rd run
Size of ArrayList<String> is: 10
Size of ArrayList<Thread> is: 100
//4th run
Size of ArrayList<String> is: 61
Size of ArrayList<Thread> is: 100
//5th
Size of ArrayList<String> is: 69
Size of ArrayList<Thread> is: 100
應該如何修改代碼以完整ArrayList<String>存盤所有輸出?
編輯:我按如下方式更改了代碼,但輸出是相同的。
ArrayList<Thread> threadList = new ArrayList<Thread>();
//ArrayList<String> threadListStr = new ArrayList<String>();
List<String> threadListStrSync = Collections.synchronizedList(new ArrayList<>());
int threadNumber = 100;
for (int i = 0; i < threadNumber; i ) {
String tId = String.valueOf(i);
Thread thr = new Thread(() -> {
threadListStrSync.add(calculateHash(tId));
});
threadList.add(thr);
}
// START the threads
for (int i = 0; i < threadNumber; i ) {
threadList.get(i).start();
}
// STOP the threads
for (int i = 0; i < threadNumber; i ) {
threadList.get(i).interrupt();
}
System.out.println("Size of ArrayList<String> is: " threadListStrSync.size());
System.out.println("Size of ArrayList<Thread> is: " threadList.size());
注意:我評論了,interrupt();但輸出仍然相同。
uj5u.com熱心網友回復:
有多個問題
- 使用執行緒安全集合或手動同步訪問 - 一個簡單的選擇是用
Collections.synchronizedList() interrupt()不需要,執行緒將在到達其run()-method的末尾時終止- 您需要等待所有執行緒在列印結果之前終止 - 要做到這一點,呼叫
join()而不是interrupt()
uj5u.com熱心網友回復:
您有兩個問題:1) 可能有些執行緒在執行程序中永遠無法將其哈希 ID 添加到集合中,以及 2) 多個執行緒正在訪問哈希 ID 的集合,因此您應該使用執行緒安全的集合.
ArrayList<Thread> threadList = new ArrayList<Thread>();
Collection<String> threadListStr = Collections.synchronizedCollection( new ArrayList<String>() );
int threadNumber = 100;
for (int i = 0; i < threadNumber; i ) {
String tId = String.valueOf(i);
Thread thr = new Thread(() -> {
threadListStr.add(calculateHash(tId));
});
threadList.add(thr);
}
// START the threads
for (int i = 0; i < threadNumber; i ) {
threadList.get(i).start();
}
// STOP the threads
for (int i = 0; i < threadNumber; i ) {
try {
threadList.get(i).join();
} catch( InterruptedException exc ) {
// handle interrupted exception
}
}
System.out.println("Size of ArrayList<String> is: " threadListStr.size());
System.out.println("Size of ArrayList<Thread> is: " threadList.size());
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/359338.html
