views:

84

answers:

3

I have to call a function 3rd party module on a new thread. From what I've seen, the call either completes quickly if everything went well or it just hangs for ever locking up the thread. What's a good way to start the thread and make the call and wait for a few secs and if the thread is still alive, then assuming it's locked up, kill (or stop or abandon) the thread without using any deprecated methods.

I have something like this for now, but I'm not sure if this is the best way to do it and I want to avoid calling Thread.stop() as it's deprecated. Thanks.

private void foo() throws Exception
{
        Runnable runnable = new Runnable()
        {

            @Override
            public void run()
            {
                    // stuff that could potentially lock up the thread.
            }
        };
        Thread thread;
        thread = new Thread(runnable);
        thread.start();
        thread.join(3500);
        if (thread.isAlive())
        {
            thread.stop();
            throw new Exception();
        }

}
A: 

I would look into the java.util.concurrent Executor framework and specifically the Future<T> interface. with these you are abstracted somewhat from the vagaries of java.lang.Thread, and you get good decoupling of what the tasks are from how they are run (whether on a separate thread, whether the thread comes from a pool or is instantiated on the fly, etc.)

A Future instance, at least, gives you isDone and isCancelled methods.

The ExecutorService (subinterface of Executor) gives you some means of shutting down any outstandings tasks. Or check out the ExecutorService.awaitTermination(long timeout, TimeUnit unit) method

private void foo() throws Exception
{
        ExecutorService es = Executors.newFixedThreadPool(1);

        Runnable runnable = new Runnable()
        {

            @Override
            public void run()
            {
                    // stuff that could potentially lock up the thread.
            }
        };

        Future result = es.submit(runnable);

        es.awaitTermination(30, TimeUnit.SECONDS);

        if (!result.isDone()){
            es.shutdownNow();
        }

}
Scott Bale
+2  A: 
public void stop() {
        if (thread != null) {
           thread.interrupt();
        }
    }

See this link on How to Stop a Thread, it covers the subject well

Romain Hippeau
I'm down voting because calling your method 'stop' shows a naive and incorrect understanding of Thread interrupting at best. As an FYI @Romain Hippeau, just because you call interrupt on a thread does not mean it will stop. If the implementation of this code is poor enough to cause deadlock, then it is certainly poor enough to mishandle an InterruptedException or not check the interrupt flag appropriately.
Tim Bender
@Tim Bender - The question is how to stop a Thread. The implementation of the routine is not part of the question. If you read the link I have in the answer it covers all that. For the record let it be shown "I do not think the down vote was fair". P.S. thanks for putting an explanation why instead of just downvoting (I hate that)
Romain Hippeau
+1  A: 

There is no way to do what you want (unconditionally). For example if the stuff that could potentially lock up the thread. looks like this, there is no way to stop it, ever short of System.exit():

public void badStuff() {
 while (true) {
  try {
   wait();
  }
  catch (InterruptedException irex) {
  }
 }
}

When your app gets stuck, run jstack (or use the debugger). Try to figure out what sticks up the function and fix it.

Justin
Or get a JVM dump using: kill -QUIT pid
Chris J
That only works on unix, jstack is cross platform.
Justin
The function that I call is in a 3rd party module and I have no control over it, unfortunately. So, there is no way to fix it unless I get an update from the module's author.
Bala R
@Bala, You should still make an effort to determine what the problem is. Is it possible that you can only run the third party code in a single thread? If it is a deadlock issue, then simply preventing any type of concurrent execution of their code could help. Also, once you know the problem, you can insist on a fix from the third party.
Tim Bender