2017-05-10 89 views
0

下面的代碼存在於「UnderStanding the JVM Advanced Features and Best Practices,second Edition」的第13章中。 但是當線程執行「while(Thread.activeCount()> 1)」時,它將被阻塞並且不會打印任何內容。爲什麼線程在執行代碼時被阻塞「while(Thread.activeCount()> 1)」?

public class Code_12_1 { 
public static AtomicInteger race = new AtomicInteger(0); 

public static void increment(){ 
    race.incrementAndGet(); 
} 

private static final int THREADS_COUNT = 20; 
public static void main(String[] args) throws Exception{ 
    Thread[] threads = new Thread[THREADS_COUNT]; 
    for (int i = 0; i < THREADS_COUNT; i++) { 
     threads[i] = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       for (int j = 0; j < 10000; j++) { 
        increment(); 

       } 
      } 
     }); 
     threads[i].start(); 
    } 

    while (Thread.activeCount() > 1) 
     Thread.yield(); 

    System.out.println(race); 
} 

}

但是,當我改變 「而(Thread.activeCount()> 1)」 到 「而(Thread.activeCount()> 2)」 的線程可以正確地執行和輸出的答案200000.

那麼,爲什麼線程在執行時會被阻塞「while(Thread.activeCount()> 1)」?

+0

您沒有爲您的線程指定一個組,以便它由JVM分配,而且似乎使用的組已在您創建的線程之上有一個正在運行的線程。 – assylias

+0

java doc中的'activeCount'方法:「返回的值只是一個估計值,因爲線程數可能會動態變化,而此方法會遍歷內部數據結構,並且可能會受到某些系統線程的影響。用於調試和監控目的。「所以,這只是估計的數字,並可能受系統線程影響。你不應該依賴'activeCount',而應該使用'join'。 – binhgreat

回答

0

我已經想通了。我運行了你的代碼,事實證明,除了主線程(在當前的ThreadGroup中)之外,還有另一個線程正在運行,甚至在所有其他線程之前。所以,下面的打印語句給我計數2(見initialCount):

public static void main(String[] args) throws Exception{ 
     Thread[] threads = new Thread[THREADS_COUNT]; 

     int initialCount = Thread.activeCount(); 
     System.out.println("Initial count: " + initialCount); 

     for (int i = 0; i < THREADS_COUNT; i++) { 
      threads[i] = new Thread(new Runnable() { 
       @Override 
       public void run() { 
        for (int j = 0; j < 10000; j++) { 
         increment(); 

        } 
       } 
      }); 
      threads[i].start(); 
     } 

     while (Thread.activeCount() > 1){ 
      System.out.println(race); 
      System.out.println(Thread.activeCount()); 
      Thread.yield(); 
     } 
} 

所以,你要做的是:

​​

而且,預期它會工作。

推理:它被阻塞是因爲所有線程在啓動它們後都會執行完畢,然後您還剩下這個額外的線程,永遠不會讓您退出while循環。

如果Thread.yield()之前插入打印語句,你會得到一個輸出一樣,

200000 
200000 
200000 
200000 
200000 
200000 
... 
... 

這支持了所有的線程完成,只是2離開的保持環運行的理由。

+0

謝謝,你說得對。但我明白爲什麼會發生。如果我使用eclipse來運行代碼,那麼代碼「while(Thread.activeCount()> 1)」沒有問題。但是如果我使用Intellij IDEA,它會有問題。由於IDEA將啓動一個名爲「Monitor Ctrl-Break」的新線程,因此活動線程數爲2. [link](https://github.com/JetBrains/intellij-community/blob/master/java/java-運行/ SRC/COM /的IntelliJ/RT /執行/應用/ AppMainV2.java) –

相關問題