[英]What is the reason of not executing all of the threads in an unbounded threadpool executer
我正在使用ExecutorService
ExecutorService executor = Executors.newFixedThreadPool(20000);
我在ThreadSystem.java
類中有兩個靜態成員:
public static Integer count = 0;
public static Integer rejectedCount = 0;
然后我向其中添加線程:
for (i = 0; i < 20001; i++) {
Runnable worker = new MyThread();
try {
executor.execute(worker);
} catch (RejectedExecutionException ex) {
rejectedCount++;
}
}
executor.shutdown();
while (!executor.isTerminated()) {
}
在線程內:
@Override
public void run() {
ThreadSystem.count++;
try{
Thread.sleep(50);
}
catch(InterruptedException ex){
Logger.getLogger(MyThread.class.getName()).log(Level.SEVERE, ex.getMessage(),ex);
}
}
我得到的結果表明,有未執行的線程和count
變量不等於創建的線程數,雖然rejectedCount
是指被拒絕的線程是0:
數量:19488
拒絕計數:0
那么還有什么可以保證我所有線程都將運行,那是什么原因: count(可運行線程)不等於添加的線程 ?
您的代碼是競爭條件的“完美范例”:您可以訪問
public static Integer count = 0;
未同步,因此多個線程可以同時執行以下操作:
ThreadSystem.count++;
這可能/可能導致寫入丟失,因為多個線程可能同時執行ThreadSystem.count = ThreadSystem.count + 1
的等效ThreadSystem.count = ThreadSystem.count + 1
,並且某些線程將讀取該操作的舊的但尚未更新的數字。
請使用適當的synchronized
防護程序,或者在AtomicInteger#incrementAndGet()
使用某些計數器。
請注意,在這種情況下,您不得同步count
,因為Integer
是不可變的對象,並且對裝箱原語( int
到Integer
, long
到Long
,...)的操作基本上是對該變量的賦值。 使用AtomicInteger
是解決此給定問題的最佳解決方案。
您的 (不正確,因為這僅由一個線程更新。) rejectedCount
也是如此。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.