1

I am trying to create a solution to treat hung threads due to memory leaks, locked resources in our applications. One of the main problems I am having is trying to simulate a hung thread to deal with it. Any sugestions?

This is what I tried, but it just doesn't seem to do the job. Any thoughts?

class KillerThread extends Thread{

    public KillerThread() {
        super();
    }
    public KillerThread(String threadName) {
        super(threadName);
    }
    public void run (){
        System.out.println("Start of KillerThread " + this.getName() );
        if ( System.currentTimeMillis() % 2L == 0 ){
            try {
                sleep(Long.MAX_VALUE);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            for(;;);
        }
    }
}
Kara
  • 6,115
  • 16
  • 50
  • 57
readikus
  • 369
  • 1
  • 6
  • 17
  • 1
    did you check http://stackoverflow.com/questions/3203139/how-do-you-hang-a-thread-in-java-in-one-line – naresh Mar 07 '12 at 11:35
  • Works for me. How are you starting the thread? – adarshr Mar 07 '12 at 11:35
  • 1
    what do you mean by "hung"? do you mean that even `interrupt()` won't do anything? – Yanick Rochon Mar 07 '12 at 11:42
  • 3
    How is it hanging? Is it deadlocking, sleeping forever or busy waiting forever. It matters because each has a different solution. – Peter Lawrey Mar 07 '12 at 11:43
  • @Peter Lawrey - we "suspect" that certain threads are "hanging" as they are waiting for a response from a port (which never comes). Would this be the same as sleeping forever? The basic solution we want is to keep track of the threads along with the time they were created. If they have been running for 20 minutes, kill the threads without having restart the main Java program. Is this realistically possible? – readikus Mar 07 '12 at 11:56
  • 1
    do you have control over the implementation of these "hanging" threds? If so, I would suggest using a ThreadPoolExecutor, and invoking the task via a Callable interface (see FutureTask : http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/FutureTask.html and the Java Concurrent API) – Yanick Rochon Mar 07 '12 at 12:13

6 Answers6

3

Joining on one's own thread works well for me:

Thread.currentThread().join();
Robert Važan
  • 3,399
  • 2
  • 25
  • 31
2

try running sleep in a while loop like:

while(true) {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
Maarten Blokker
  • 604
  • 1
  • 5
  • 23
  • My IDE gives me a warning message `Thread.sleep called in loop`? –  Jun 11 '15 at 16:13
  • Wow, old answer! Yeah generally sleeping in a loop leads to poor performance. Your IDE (netbeans) gives a warning about this. For the sake of the question, this can be ignored. – Maarten Blokker Jun 12 '15 at 08:21
0

Here's a quick fix I'm using for testing. Just have the thread you want to lock up call new Hanger().hang().

Remove the logging if you're not interested in seeing it. You can add throws InterruptedException (although, in fact, it never does) to the hang method so you can just replace a Thread.sleep() with a new Hanger().hang() without otherwise modifying your code.

public class Hanger {

  private final static Logger log = Logger.getLogger(Hanger.class);
  private long started = 0;
  private final int beat = 100; // ms

    /**
     * Hangs a thread for the indicated time
     * @param millis  the amount of time to hang the thread, in milliseconds
     */
     public void hang(int millis) {
        started = System.currentTimeMillis();
        log.debug("Hanging this thread for " + millis + " ms");
        while (hung() < millis) {
            try {
                Thread.sleep(beat);
            } catch (InterruptedException e) {
                log.debug("Still hanging, will release in " + (millis - hung()) + " ms.");
            }
        }

        log.debug("Releasing thread again after " + hung() + " ms");
    }

    private int hung() {
        return (int)(System.currentTimeMillis() - started);
    }
}
PapaFreud
  • 3,636
  • 4
  • 34
  • 45
0

running a thread then tell it to sleep in an unstoppable loop, is a good idea,. but how if you are trying to make it waiting another thread,.? make more than one thread and make them wait one each other, a deadlock condition, is that a hung to,.?

simaremare
  • 401
  • 2
  • 10
0

Simply enough, just create a private member

private Object lock = new Object();

then use it to wait for a notification (that will never happen, unless you use reflection...)

while (true) {
   try {
      synchronized (lock) {
         lock.wait();
      }
   } cath (InterruptedException e) {
      /* ignore interruption */
   }
}

and you thread will hang there, uninterruptable.

Yanick Rochon
  • 51,409
  • 25
  • 133
  • 214
0

I know what you need exactly, you are testing something through stopping the executor thread. Try something like this:

private void testKillingThread() {
    Object kill = new Object();
    try {
        synchronized (kill) {
            kill.wait();
        }
    } catch (Exception e) {
        // Auto-generated catch block
    }
}
GingerHead
  • 8,130
  • 15
  • 59
  • 93
  • You need to use `while(true) { kill.wait(); }` to protect against spurious wakeups. See: http://stackoverflow.com/a/3203164/257299 – kevinarpe Oct 16 '15 at 02:08
  • @kevinarpe But how this is possible when it's secured with synchronized – GingerHead Oct 16 '15 at 09:22
  • Good question. Spurious wakeups are very complex(!). Imagine a traditional POSIX signal, such as `SIGUSR1`, is sent (via `kill` command line tool) to your process. By POSIX rules (AFAIK), the kernel will wakeup each sleeping/waiting thread and notify incoming signal. This is the classic case for why programmers need to check a predicate (boolean case) if the wait condition is satisfied. Ref about JVM+signals: http://www.oracle.com/technetwork/java/javase/signals-139944.html – kevinarpe Oct 16 '15 at 10:16
  • And in this particular case synchronized surrenders that easily??!! – GingerHead Oct 20 '15 at 17:34