2017-09-26 97 views
2

我運行下面的代碼,以顯示我的程序正在運行的線程杭發生時Thread.getAllStackTraces()被調用

public void printTasks() { 
    System.out.println("get threads start"); 
    for (Thread thread : Thread.getAllStackTraces().keySet()) { 
     //This block filters the non-java threads running 
     if (!thread.getThreadGroup().getName().equals("system")) { 
      System.out.println("hello"); 
     } 
    } 
    System.out.println("get threads end"); 
} 

問題,有時代碼只是打印後掛起「獲得線程開始「,我懷疑掛起發生在這一行」Thread.getAllStackTraces()「

注意:我的程序使用線程執行一組任務,因此,它創建了約70個線程,並且掛起是間歇性的,每6或7次只有一次,我稱這種方法的問題出現

我的問題是:

  • 這是一個已知的問題嗎?
  • 有沒有辦法來防止這種行爲?
  • 是否有更安全的方法列出正在運行的線程?

編輯:我用java 1.8,這個問題發生在Linux的OEL和Windows Server,在這兩種情況下,它是間歇性的,軟件運行作爲獨立的桌面應用程序

預先感謝您

+1

您運行的是什麼版本的Java,以及在什麼操作系統?這是一個獨立的應用程序還是某種應用程序服務器? –

回答

0

我剛剛發現問題是什麼(至少這是我的假設)。

用於檢索正在運行的線程的代碼遇到競爭條件。

我的程序被創建在不斷變化的線程,一些啓動他人結束的時間非常短的時間(1秒或更少)

Thread.getAllStackTraces()返回線程和棧跟蹤(線的HashMap中功能一個),然後在下一行(b線),我試圖讓線程的組名

for (Thread thread : Thread.getAllStackTraces().keySet()) { <--- a 
    if (!thread.getThreadGroup().getName().equals("system")) { <--- b 

但線程持續這麼小,它消失達到第二條線之前,因此我最終想使用無效密鑰從地圖獲取值(thi S爲比賽條件)

注意:如果你從來沒有經歷過這種情況,當你嘗試讀取不存在,你可能最終爲結果

永遠等待一個HashMap的值

解決方案

確保線程試圖讀取它的屬性

public void printTasks() { 
    System.out.println("get threads start"); 
    for (Thread thread : Thread.getAllStackTraces().keySet()) { 
     //This block filters the non-java threads running 
     if (Thread.getAllStackTraces().containsKey(thread) && //<--new line here 
      thread.getThreadGroup().getName().equals("system")) { 
      System.out.println("hello"); 
     } 
    } 
    System.out.println("get threads end"); 
} 

第二種方法是將前仍然存在試圖讓getAllStackTraces的內容的快照()來讀取不可變對象

更好的解決方案是值得歡迎的,希望這可以幫助別人

相關問題