2017-09-26 49 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的内容的快照()来读取不可变对象

更好的解决方案是值得欢迎的,希望这可以帮助别人

相关问题