Thread.stop() (no don't go away, please read!!!)

  • Thread starter anthony.jayasekera
  • Start date
A

anthony.jayasekera

Hi,
Like many before me I have recently been wrestling with the fact that
Thread.stop() has been deprecated and as such, if I want to halt a
thread during some processing that does not periodically check whether
to keep going or have the potential to throw InterruptedException's, I
basically have to go fly a kite! I have read the reason why
Thread.stop() is bad, namely that it unlocks any monitors associated
with the thread (I am not aware of any other problems). However I
believe that in my particular scenario this may not be an issue. Here
is my scenario:

I am trying to implement a cancellable, modal WaitDialog for display
whilst executing long running code. In my specific usage of this dialog
the long running code is wrapped up in a single third party api call
over which I have no control. It does not throw InterruptedException's
and can take a very long time to execute.

The only monitor I explicitly assign is one which locks access to
disposal of the dialog. My worker thread executes the long running code
and once completed disposes of the dialog in a locked section of code.
Importantly, this code checks to see if the dialog is disposed (using
isDisplayable()) before disposing it. The click handler for the cancel
button on the WaitDialog also performs this checked dispose.
From my calling thread I start the worker thread and display the
WaitDialog (using Dialog.setVisible()). Since the dialog is modal
control leaves the calling thread at this point. When control returns
to the thread (i.e. when the dialog has been disposed) I check to see
if the worker is still running (using isAlive()) and if so, ......, I
call Thread.stop()!!! The isAlive check and stop call are also done in
a block synchronised on the same monitor as the dispose code.

So, when I call Thread.stop() the only lock affected is the one
sychronising the the disposal. If it is unlocked and the worker thread
is currently waiting on it the waiting synchronised code won't execute
since Thread.stop() can only be called after the dialog has been
disposed (remember it checks to see if the dialog is disposed before
executing).

Therefore, as far as I can see there will be no adverse affects of
calling Thread.stop() in this situation. Of course if there are any
implicit monitors that my application code doesn't know about that
would be a different matter. Is there anything like this?

Of course I haven't even approached the possibility that the deprecated
stop method may be dropped entirely but if this scenario is a valid one
perhaps the method should not be dropped?


Any opinions about this would be gladly received.

Thanks,

Anthony
 
B

Bent C Dalager

Therefore, as far as I can see there will be no adverse affects of
calling Thread.stop() in this situation. Of course if there are any
implicit monitors that my application code doesn't know about that
would be a different matter. Is there anything like this?

It would depend on the implementation of the third-party method you
are calling. If part of its operation includes updating state
information that is visible outside of the operation itself, it could
leave the third-party API in an inconsistent state. Consider, for
example, if the operation contains code to the effect of:

GlobalData.contextIsValid = true;
GlobalData.context = someValidContext;

If your Thread.stop() takes effect after the first line but before the
second line, the API may be left thinking it has a valid context set
when, in fact, it does not. This could seriously mess up subsequent
calls to the API.

I am sure this is not the only way in which Thread.stop() could be
problematic in your case, but it is, at least, one :)

Cheers
Bent D
 
T

Thomas Hawtin

Therefore, as far as I can see there will be no adverse affects of
calling Thread.stop() in this situation. Of course if there are any
implicit monitors that my application code doesn't know about that
would be a different matter. Is there anything like this?

Expect code not to work with asynchronous exceptions. In the presence of
asynchronous exceptions you can't even assign two references knowing
that they will either both or neither be assigned.

Also think about class loading. You call a stop whilst a static
initialiser is running. What happens? The static initialiser throws. A
linkage error is caused. The class will never load under that class
loader ever again (IIRC). Thread.interrupt can do the same thing,
incidentally.

Tom Hawtin
 
R

Roedy Green

ny opinions about this would be gladly received.

Here is a Thread class that you can stop gently.

package com.mindprod.common11;

/**
* A Thread you can stop gracefully. Remember nullify references to
the thread
* after you are finished. Threads are big. You can't restart it!
version 1.0
* 2002-08-01 version 1.1 2002-08-02 Make pleaseStop volatile and
synchronize
* access to it. Required for multi-cpu cache synchronization.
*
* @author Roedy Green
*/
public class StoppableThread extends Thread {

/**
* true when we want the current run method to stop as soon as it
can.
* volatile so threads will take always take a fresh look at what
other
* threads have set.
*/
private volatile boolean pleaseStop = false;

/**
* Stop this thread gracefully. If the thread is already stopped,
does
* nothing. For this to work, this.run must exit by checking
stopping() at
* convenient intervals and returning if it is true.
*
* @param interrupt
* true if this thread should be interrupted from sleep or
from doing
* an i/o (which might close the channel), before stopping
it.
* @param timeout
* How long in milliseconds to wait for the thread to die
before
* giving up. 0 means wait forever. -1 means don't wait at
all.
*/
public void gentleStop ( boolean interrupt, long timeout )
{
if ( !this.isAlive() ) return;
synchronized ( this )
{
// ask thread to stop.
this.pleaseStop = true;
}
// wake this thread up if it is sleeping,
// and get it to notice stopping() flag.
// Will also interrupt i/o.
if ( interrupt )
{
this.interrupt();
}

if ( timeout >= 0 )
{
try
{
// wait for the thread to die.
this.join( timeout );
}
catch ( InterruptedException e )
{
}
}
} // end stop

/**
* Start this thread executing its run method on a separate
thread. You may
* only call start once. After the thread dies it cannot be
restarted.
*
* @exception IllegalThreadStateException
* if this thread is already started.
*/
public void start ()
{
super.start();
}

/**
* this.run should call stopping() at convenient invervals to see
if it has
* been requested to stop. If true, it should finish up quickly
and return.
* Will have to be called via while ( !
* ((StoppableThead)Thread.currentThread()).stopping() )
*
* @return true if run should exit soon.
*/
public synchronized final boolean stopping ()
{
return pleaseStop;
}

/**
* Constructor.
*
* @param r
* Class that has a run method
*/
public StoppableThread( Runnable r )
{
super( r );
}

} // end StoppableThread
 
S

Steve Horsley

Hi,
Like many before me I have recently been wrestling with the fact that
Thread.stop() has been deprecated and as such, if I want to halt a
thread during some processing that does not periodically check whether
to keep going or have the potential to throw InterruptedException's, I
basically have to go fly a kite! I have read the reason why
Thread.stop() is bad, namely that it unlocks any monitors associated
with the thread (I am not aware of any other problems).

Have you considered running this method in a separate process
(make a wrapper if needed) and driving it through a Process? You
can have the wrapper output the results on stdout for you to
read, and can use Process.destroy to kill it if you get tired of
waiting.

Steve
 
C

Chris Uppal

Steve said:
Have you considered running this method in a separate process
(make a wrapper if needed) and driving it through a Process?

Indeed, that is (on common OSes[*][**]) the /only/ safe way to interrupt a
computation that has not been written to co-operate with calling code.

-- chris

(
[*] short of turning the machine off....

[**] actually I don't know of any uncommon OS where this is possible either,
but I can imagine that they exist.
)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,054
Latest member
LucyCarper

Latest Threads

Top