簡體   English   中英

不執行無限制線程池執行程序中所有線程的原因是什么?

[英]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是不可變的對象,並且對裝箱原語( intIntegerlongLong ,...)的操作基本上是對該變量的賦值。 使用AtomicInteger是解決此給定問題的最佳解決方案。

您的rejectedCount也是如此。 (不正確,因為這僅由一個線程更新。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM