2017-10-12 26 views
3

您好我想用一個靜態列表保存所有正在運行的線程,如:使用靜態列表,以保持所有線程Java中

public class MyClass { 
    public static final List<Thread> threads = new ArrayList<>(); 
    public static void main(String[] args) throws InterruptedException { 
     new Thread(() -> { 
      MyClass.threads.add(Thread.currentThread()); 
      try { 
       Thread.sleep(2000); 
      } catch (Exception e) { 
      } 
     }).start(); 
     for (int i = 0; i < 10; i++) { 
      if (!threads.isEmpty()) { 
       Thread t = threads.get(0); 
       System.out.println(t.isAlive()); 
      } 
      Thread.sleep(1000); 
     } 
    } 
} 

上面的代碼將會給打印出來的

true 
true 
false 
false 
... 

這和線程返回2秒後的預期一樣。

我的問題是:線程添加到靜態線程列表是否在線程返回後消失?即我希望在線程返回後的某個時間點看到列表中的線程對象是否爲空?或者我會無限期地看到線程對象嗎? GC在這裏扮演什麼角色?

+3

*不添加到線程的靜態列表線程永遠消失線程返回之後*?只有當你將其刪除。 –

回答

4

線程對象不會奇蹟般地消失,一旦相關的OS線程終止。

一旦線程被終止,它不能作爲GC根,但只要別的東西保持對它的引用,就像你的列表一樣,它會一直存在。

而且不要緊線程是否停止或中斷或什麼的。 java.lang.Thread是一個對象,只要該線程處於活動狀態,就會引用系統資源(實際的線程),但一旦該線程終止,不會執行任何操作來銷燬該對象。只是isAlive返回false,你不能再成功地調用它的開始。

很難想象它會做什麼來保持線索列表,比如你的建議。

+0

謝謝。我在構建MyClass時添加了線程,以便我知道誰擁有它的一個實例。 – user1589188

+1

@ user1589188:你最好使用線程池而不是專用線程。 –

+0

謝謝。幾乎完美的答案。現在,如果我調用remove來釋放線程對象的最終引用,那麼GC將重用線程佔用的資源吧? – user1589188

1

不,線程不再運行,但您持有的Thread對象將保持不變,就像任何其他對象一樣。垃圾回收器只能清理沒有任何引用的對象,並且Thread實例也不例外。