简体   繁体   中英

Hang occurring when Thread.getAllStackTraces() is called

I'm running the below code to display the running threads of my program

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");
}

the problem is that sometimes the the code hangs just after print "get threads start", I suspicious the hang happens in this line "Thread.getAllStackTraces()"

Note: My program performs a set of tasks using threads, due to this, it creates about ~70 threads and the hangs is intermittent, only 1 of every 6 or 7 times that I call this method the issue shows up

my questions are:

  • Is this a known issue?
  • Is there a way to prevent this behavior?
  • Is there a safer method to list the running threads?

Edit: I'm using java 1.8, the issue happens in Linux OEL and Windows Server, in both cases it is intermittent, the software is run as standalone desktop application

Thank you in advance

I just found out what the problem was (at least this is my hypothesis).

The code used to retrieve the running threads was experiencing a race condition.

The threads that my program was creating are constantly changing, some start others end in very short periods of time (1 second or less)

the function Thread.getAllStackTraces() returns a HashMap of thread and stack trace (line a) and then in the next line (line b) I was trying to get the thread's group name

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

but the thread lasted so little that it disappeared before the second line was reached and thus I ended up trying to get a value from the map using an invalid key (this was the race condition)

Note : in case that you never had experienced this before, when you try to read the value of a HashMap that doesn't exist you might end up waiting forever for the result

Solution

Ensure the thread still exists before trying to read its attributes

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");
}

A second approach would be to try to get an snapshot of the content of getAllStackTraces() to read immutable objects

A better solution is welcome, hope this helps someone

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM