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:
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.