What is so bad aboud Thread.stop() ?

T

taqmcg

(e-mail address removed) wrote:




But that's my point here (or one of them): The objects you use to communicate
with the other thread are necessarily both shared and mutable by that thread
(or else how can it use them to communicate ?). Given that, it's hard tomake
/those objects/ safe if you are considering killing the other thread
asynchronously -- since it may be in the middle of /using/ (modifying) them
when it's killed.

You can use objects that are readonly to the stoppable thread to send information to that thread, and use objects that are read by the monitor (or other threads) only after the thread has successfully finished (or at least completed the tasks during which it may be stopped) to get information back.
The fact that I might have stopped the thread in some circumstances doesn'tmean I can't use objects created by it when I do let it finish.
I'm not saying it's impossible to create an efficient, Thread-stop()-safe,
shared communication channel, but I don't think it's easy (polling is probably
the best bet). And I doubt if you'll find ant *semi-)"official" ones -- why
would anyone bother when Thread.stop() is so widely shunned ?
I wasn't really thinking about a dialog between threads, but that shouldn't
be too hard either. Suppose you use an object X to carry on the dialog, mutable by both threads. No special problems before you stop the thread. After stopping a thread you recognize that X is damaged and throw it away. Any object that the monitor thread can access that could have been mutated by the stopped thread is suspect, but simply discarding them is easy enough.I don't think a damaged object has cooties and affects a program just by being there. It has to be used in some way that lets the damaged state manifest itself. That could be subtle (say it does something in its finalizer), but it should be knowable.

Thanks for your comments. I'm playing the devil's advocate here to try to draw out specifics of why it would be so difficult to handle the consequences of stopping a thread, but since it has been, as you say, widely shunned,it doesn't seem like there is too much experience actually using it. Of course the fact that people haven't had to use it does mean that at least most of the time there are alternatives, though some (e.g., a separate JVM) may be very heavyweight.

Regards,
Tom
 
T

taqmcg

Lew is an experienced programmer.
He would never waste hours investigating something that is
known to be a bad solution from the beginning.

Arne

My point is not to disparage anyone here, but to point out that even very skilled programmers sometimes have an incorrect knowledge of how something they haven't used works. That may affect their evaluation of its utility.

Regards,
Tom
 
K

Kevin McMurtrie

Chris Uppal said:
Can the behaviour of Thread.stop() be relied on ? For an API that has been
deprecated since the early Pleistocene, (and which -- if my very vague memory
is roughly correct -- has never been implemented correctly anyway) it seems
that implementers have the right to do practically anything. It's not as if
we
haven't been warned.

-- chris

Native thread stopping is definitely implemented in some way. It's
what's called when the JVM is quitting. What's not guaranteed is that
Thread.stop() is connected to it.

You can maybe use Thread.stop() with design patterns based on
compare-and-set. CAS is an atomic operation at the CPU level used for
non-blocking multithreading. It exactly runs or does not run, with
nothing in between. The design is essentially:

ImmutableThing originalThing, newThing;
do
{
originalThing = atomicRef.get();
if (originalThing.hasData(myChanges))
break;
newThing= new ImmutableThing (originalThing, myChanges);
} while (!atomicRef.compareAndSet(originalThing, newThing));

Of course you're still completely screwed if you happen to call
Thread.stop() while some line of code is invoking the ClassLoader or a
static initializer.
 
B

blmblm

You can use objects that are readonly to the stoppable thread to send
information to that thread, and use objects that are read by the
monitor (or other threads) only after the thread has successfully
finished (or at least completed the tasks during which it may be
stopped) to get information back. The fact that I might have stopped
the thread in some circumstances doesn't mean I can't use objects
created by it when I do let it finish.

That *sounds* plausible .... But it occurs to me that assigning values
to variable is no longer a simple matter -- with smart compilers and
caches and so forth, it's hard to be sure when the value will actually
be visible to other threads, which is presumably why the Java memory
model (with its "happens before" and so forth) exists. Can someone who
knows that model comment on how it might apply here?
 
T

taqmcg

...


That *sounds* plausible .... But it occurs to me that assigning values
to variable is no longer a simple matter -- with smart compilers and
caches and so forth, it's hard to be sure when the value will actually
be visible to other threads, which is presumably why the Java memory
model (with its "happens before" and so forth) exists. Can someone who
knows that model comment on how it might apply here?


B. L. Massingill
It's certainly true that the memory model is abstruse, but that's true of interthread communications generally and not specific to killed threads.

If I have an object that is mutable by a thread that I might kill at some point, it would be pretty nifty if the fact that the thread was going to be killed in the future affected it before I killed it...a thiotimoline thread! And after the monitor kills a thread, it seems like discarding all potentially mutated objects should be a pretty robust way to limit the effects.

But I'd agree that if there is a third thread involved, things get a lot more complex -- though again that's true of thread communication generally.

Tom McGlynn





might be killed in the future could affect it before I kill it
 
B

blmblm

It's certainly true that the memory model is abstruse, but that's true of
interthread communications generally and not specific to killed threads.


Agreed. (Do I seem to be saying otherwise?) Indeed, that's
the point I was trying to make in saying "that's why the Java
memory model exists" -- meaning that without a model, it would
be difficult if not impossible to say anything meaningful about
when one could rely on values being visible to other threads.
If I have an object that is mutable by a thread that I might kill at some
point, it would be pretty nifty if the fact that the thread was going to be
killed in the future affected it before I killed it...a thiotimoline thread!


Um, I don't get the connection between this and what I wrote. ?

And after the monitor kills a thread, it seems like discarding all
potentially mutated objects should be a pretty robust way to limit the
effects.


Um, yes .... So you're saying if thread A kills thread B, to be
safe thread A should also discard any objects potentially mutated
by thread B?

But I'd agree that if there is a third thread involved, things get a lot more
complex -- though again that's true of thread communication generally.


Third thread? Now I'm really confused.


But to get back to your presumably-safe scenario, in which thread B
finishes normally. It seems reasonable to assume that all values
assigned in thread B should then be visible to other threads.
What I'm wondering, though, is whether that's explicitly required
by the Java memory model. (Yeah, yeah, really I should probably
just go read up on the memory model myself, but I thought someone
else might know, and that this might be an interesting point to
raise anyway.)
 
T

taqmcg

Agreed. (Do I seem to be saying otherwise?) Indeed, that's
the point I was trying to make in saying "that's why the Java
memory model exists" -- meaning that without a model, it would
be difficult if not impossible to say anything meaningful about
when one could rely on values being visible to other threads.



Um, I don't get the connection between this and what I wrote. ?


Um, yes .... So you're saying if thread A kills thread B, to be
safe thread A should also discard any objects potentially mutated
by thread B?


Third thread? Now I'm really confused.

But to get back to your presumably-safe scenario, in which thread B
finishes normally. It seems reasonable to assume that all values
assigned in thread B should then be visible to other threads.
What I'm wondering, though, is whether that's explicitly required
by the Java memory model. (Yeah, yeah, really I should probably
just go read up on the memory model myself, but I thought someone
else might know, and that this might be an interesting point to
raise anyway.)




B. L. Massingill
Sorry if I have confused things -- I'm not disagreeing with you I think. I'd be delighted to get an informed response that clearly referenced the formal memory model. However my particular issue in this thread is trying to understand what is especially dangerous about using Thread.stop(). The general complexity of inter-thread communications is a given, but not the topic I was hoping to explore.


In the two thread scenario we have four situations to consider:

1. Interactions between two threads where no stop occurs.
- Presumably not affected by Thread.stop()!
Monitor will stop thread:
2. ... but it hasn't happened yet.
In this case it's difficult to see how Thread.stop() can have an
effect before it is called -- unless the effect travels backward in time
hence the reference to thiotimoline. For these two threads there
should not be any difficulty in knowing if we are before or after
the method call (in the case of the monitor) or before or after the
initiation of the ThreadDeath interruption (in the case of the stopped
thread)
3. ...after the Monitor has invoked the stop method.
If any object the thread could have mutated is discarded immediately
upon return from the stop call it's hard to see how any invalid state
could get transferred to the monitor without some real weirdness in
the memory model or some kind of tbd magic.
We do need to make sure that the stopped thread dies.
4. ...While stop is running.
I didn't refer to this in the earlier message, but
the way stop is described, it doesn't actually do anything that should
directly affect the memory (it just throws an exception). But I'd agree
that an informed opinion would be helpful.

My reference to three threads was intended to note that if we had other threads that could see to the objects the stopped thread could mutate, that itcould be harder to ensure that invalid state did not escape, nothing more.

So again, I don't think I'm disagreeing with your basic point regarding thememory model, but I am trying to see what is new that Thread.stop brings to that consideration versus other mundane and accepted Thread interactions.

Regards,
Tom McGlynn
 
L

Lew

I am trying to see what is new that Thread.stop brings to that consideration
versus other mundane and accepted Thread interactions.

Seems to me that
http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
explains it rather well.

I found it fast via
http://lmgtfy.com/?q=Java+dangers+of+Thread.stop

You've cited part of this, presumably from the Javadocs:
"This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the
monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception
propagating up the stack). If any of the objects previously protected by these monitors were in an
inconsistent state, the damaged objects become visible to other threads, potentially resulting in
arbitrary behavior."

I'm not sure what else you need to know here. This is both normative and complete.
 
A

Arivald

W dniu 2013-08-14 00:22, Lew pisze:
Seems to me that
http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
explains it rather well.

I found it fast via
http://lmgtfy.com/?q=Java+dangers+of+Thread.stop

You've cited part of this, presumably from the Javadocs:
"This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the
monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception
propagating up the stack). If any of the objects previously protected by these monitors were in an
inconsistent state, the damaged objects become visible to other threads, potentially resulting in
arbitrary behavior."

I'm not sure what else you need to know here. This is both normative and complete.

So, if You can write thread in a way when it never create "inconsistent
objects" that are accessible from other threads, calling Thread.stop()
will be safe.

And how to make sure such condition?
For example, by using specialized queues for input and output data from
thread. Queues written in a way that guarantee that it never is
inconsistent. Yes, it is possible, using java.util.concurrent.atomic it
is possible to write lock-free and thread safe queues.

http://www.ibm.com/developerworks/library/j-jtp04186/
 
M

markspace

And how to make sure such condition?
For example, by using specialized queues for input and output data from
thread. Queues written in a way that guarantee that it never is
inconsistent. Yes, it is possible, using java.util.concurrent.atomic it
is possible to write lock-free and thread safe queues.

http://www.ibm.com/developerworks/library/j-jtp04186/


That's a clever idea, but I'm not sure I'd want to rely on it working in
production code. How much trouble is it really to not call
Thread.stop()? That's what I see as the principle argument here. I'm
not really convinced of the need for Thread.stop(), so all these
workarounds seem moot.

If one were really desperate, ok I can see having to resort to something
like this, but it seems like there has to be several bad engineering and
management decisions to get there.
 
A

Arivald

W dniu 2013-08-14 01:45, markspace pisze:
That's a clever idea, but I'm not sure I'd want to rely on it working in
production code. How much trouble is it really to not call
Thread.stop()? That's what I see as the principle argument here. I'm
not really convinced of the need for Thread.stop(), so all these
workarounds seem moot.

If one were really desperate, ok I can see having to resort to something
like this, but it seems like there has to be several bad engineering and
management decisions to get there.

I agree that Thread.stop() should be not used in standard operations.

But I still advise using lock-free queues, especially in high load and
highly multi-threading applications. Such structures does not need to
synchronize, so no thread will wait for other thread, resulting in
boosted performance.

Ans such highly multi-threading application can benefit from Thread.stop().
For example, lets assume application use MapReduce, and governing
thread/computer detects that one of threads works too long (other
threads/computers already finished same work). It may be error in code
or hardware malfunction that cause infinite loop.
In such case governing thread will use Thread.stop() to kill misbehaving
thread.
 
M

Marcel Müller

So, if You can write thread in a way when it never create "inconsistent
objects" that are accessible from other threads, calling Thread.stop()
will be safe.

And how to make sure such condition?
For example, by using specialized queues for input and output data from
thread. Queues written in a way that guarantee that it never is
inconsistent. Yes, it is possible, using java.util.concurrent.atomic it
is possible to write lock-free and thread safe queues.

http://www.ibm.com/developerworks/library/j-jtp04186/

Funny. Almost 20 years ago I developed for a platform, where channel
communication was state of the art. (Channels are like queues without a
buffer. Transfers is synchronous.) In fact the programming scheme that
established when using this channels consequently had some interesting
properties:

- Race condition were gone.
- Dead-locks were gone.
- You simply start a new thread for almost any state machine in your
application.
- The code for most of this threads fits on one or two screens and
therefore is very easy to maintain.
- The resulting code has good scalability because of the many small tasks.
- Remoting is easy, because you only need to transfer the channel messages.
- Almost all memory objects belong to exactly one thread.
- The RAM locality is high. No cache line hopping.

The drawback is, that on recent PC architectures that many threads cause
a significant overhead, although most of them are sleeping most of the time.
On the particular platform the channel communication were machine
instructions as well as thread start was a single instruction. The
scheduler was also in hardware. And sleeping threads did not consume any
resources except for their stack memory. In fact there was not even a
repository with sleeping threads or something like a unique thread-id.
And if the implementation of a thread did not introduce recursions, the
required stack memory for each thread was exactly calculated and
adjusted by the compiler. So the stack for most of the (small) threads
was orders of magnitude smaller than nowadays.


Marcel
 
T

taqmcg

Seems to me that

http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html

explains it rather well.

I found it fast via

http://lmgtfy.com/?q=Java+dangers+of+Thread.stop

You've cited part of this, presumably from the Javadocs:

"This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the
monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception
propagating up the stack). If any of the objects previously protected by these monitors were in an
inconsistent state, the damaged objects become visible to other threads, potentially resulting in
arbitrary behavior."

I'm not sure what else you need to know here. This is both normative and complete.

As discussed above in the thread my interest was that -- as this excerpt itself implies -- using Thread.stop merely initiates an exception which is then handled just as any other exception is. So what's special about it? In all of our discussion we seem to have only two characteristics that are special. The first is that ThreadDeath will not normally cause an error message. That seems pretty trivial. The second is that the exception can in principle happen anywhere in the stopped thread. However if it were easy to stop threads only in some TBD safe zone then it seems that using Thread.stop could be done robustly.

Since it seems that most commenters have limited experience with Thread.stop I've played a little with it myself. E.g., a test monitor class creates aset of worker threads. Each worker thread requests a task from the monitor, executes the task, reports the result back to the monitor, then asks forthe next task. The monitor periodically kills all threads older than somearbitrary value and creates a new replacement, caching the task that got cancelled to be rerun. The worker threads are only stoppable during the execution phase. Here's one of the classes:

package threadstoptester;

public class StoppableThread extends Thread {

private volatile boolean isStoppable = false;
private volatile boolean running = true;

synchronized protected void stoppable(boolean flag) {
if (!flag && !running) {
// Don't proceed to nonstoppable state if
// someone has already stopped the thread.
throw new ThreadDeath();
}
isStoppable = flag;
}

synchronized protected boolean running() {
return running;
}

synchronized public boolean doStop() {
if (isStoppable) {
isStoppable = false;
running = false;
this.stop();
return true;
} else {
return false;
}
}
}

The worker threads inherit this class, and the monitor thread calls the doStop method on the appropriate worker thread object which in turn calls Thread.stop
on the appropriate thread if the thread is currently stoppable.

My fairly simple implementation seems to run fine. Note that although it'snot especially complex, in terms of thread interactions this is much more involved than what I would normally do. Generally I just start one thread to do one task and throw it away when it's done. So this seems like a fairtest of whether there are some circumstances we can use Thread.stop robustly.

Of course I haven't proved anything... There could be subtle (or given my multithreading experience, obvious) bugs that just haven't surfaced in my limited testing. I've killed as many as ~40K threads so one might hope problems might emerge. Still so far this is play. But it doesn't suggest thatprograms are necessarily unstable when using Thread.stop, even promiscuously.

So where might this approach be useful:

1. Testing/running code that might include infinite loops due to bugs or user inputs.
- Better if single threaded
- Limited access to code
- Don't want overhead of starting new VM for each test
(or need some level of communication that makes separate VM inconvenient)
2. Stopping out of control tasks in some existing executor framework (e.g.., web server) where we need to clean up wayward threads.
- need to be able to identify 'stoppable' regions which may be hard.
3. As a potentially attractive alternative to the cooperative stopping mechanism in certain cases.
- When substantial code base might be implicated in cooperative approach.
- May require sandbox like approach.


The third alternative (and indeed all three) will be controversial, so I'llclose with an amplification of what I'm thinking there.

The cooperative Thread.interrupt() approach implies that the code that might be interrupted knows about this, i.e., the worker code is aware that there is some monitor. It needs to periodically check the interrupt flag and do something. This couples the invoker to the invoked in a way that's a bit unattractive. It's no big deal if it's just a simple loop to check but if there are lots of classes and methods that need to be instrumented it's not elegant.

If one has a set of code that is running where it's known that the invokingthreads are not affected except in some clearly defined way by the worker threads (e.g. a kind of sandbox), then using Thread.stop potentially decouples the monitor/invoker process from the worker code. In the right circumstances, I can imagine this being more attractive. My limited testing suggests that those circumstances need not be the null set.

That's not to say that others will or should agree with any of this, but thanks to both the user comments and my own explorations, I think I understand the issues much better. I'm intrigued by the responses discussing ways to do this that all the creation of dynamic objects that would be safe even in the presence of Thread.stop -- but that's probably more than I need to worry about now.


Thanks to all.

Regards,
Tom McGlynn
 
B

blmblm

On 8/13/2013 1:18 PM, (e-mail address removed) wrote:
...
...

"The final action in a thread T1 synchronizes-with any action in another
thread T2 that detects that T1 has terminated. T2 may accomplish this by
calling T1.isAlive() or T1.join()."

http://docs.oracle.com/javase/specs/jls/se5.0/html/memory.html#17.4.4

Thanks.

That seems fairly straightforward -- and I understand it to mean
"yes, the memory model does require that all values be visible,
assuming the thread doing the stop-another-thread then does a join()
to ensure that the stopped thread has finished".
 
B

blmblm

Sorry if I have confused things -- I'm not disagreeing with you I think. I'd
be delighted to get an informed response that clearly referenced the formal
memory model. However my particular issue in this thread is trying to
understand what is especially dangerous about using Thread.stop(). The
general complexity of inter-thread communications is a given, but not the
topic I was hoping to explore.


Yes, I understood that part -- I was wondering whether part of the danger
might be ill-defined interaction with the memory model.

In the two thread scenario we have four situations to consider:

1. Interactions between two threads where no stop occurs.
- Presumably not affected by Thread.stop()!
Monitor will stop thread:
2. ... but it hasn't happened yet.
In this case it's difficult to see how Thread.stop() can have an
effect before it is called -- unless the effect travels backward in time
hence the reference to thiotimoline. For these two threads there
should not be any difficulty in knowing if we are before or after
the method call (in the case of the monitor) or before or after the
initiation of the ThreadDeath interruption (in the case of the stopped
thread)
3. ...after the Monitor has invoked the stop method.
If any object the thread could have mutated is discarded immediately
upon return from the stop call it's hard to see how any invalid state
could get transferred to the monitor without some real weirdness in
the memory model or some kind of tbd magic.
We do need to make sure that the stopped thread dies.
4. ...While stop is running.
I didn't refer to this in the earlier message, but
the way stop is described, it doesn't actually do anything that should
directly affect the memory (it just throws an exception). But I'd agree
that an informed opinion would be helpful.

My reference to three threads was intended to note that if we had other
threads that could see to the objects the stopped thread could mutate, that
it could be harder to ensure that invalid state did not escape, nothing more.

So again, I don't think I'm disagreeing with your basic point regarding the
memory model, but I am trying to see what is new that Thread.stop brings to
that consideration versus other mundane and accepted Thread interactions.

Yes .... I think I'm still not quite getting your point about effects
*before* Thread.stop() is called, but I don't know that it's very
important anyway.

I think the point I might have been overlooking is that you're
proposing to be very careful not to use any objects potentially
modified by the stopped thread, and given that, maybe my concern
about whether their state is visible to other threads is a red
herring.
 
M

markspace

The cooperative Thread.interrupt() approach implies that the code
that might be interrupted knows about this, i.e., the worker code is
aware that there is some monitor. It needs to periodically check
the interrupt flag and do something. This couples the invoker to the
invoked in a way that's a bit unattractive.


Several low level APIs in Java check for the interrupt flag, so if your
library is calling these methods, it will check for interrupts implicitly.

Object.wait(), Thread.sleep(), most of the IO library, probably some
more which I don't recall at the moment.

Also, if you're going to be dealing with threads at all, get yourself a
copy of Java Concurrency in Practice. It's *the* state of the art for
working with threads in Java.

I'll also link to this article by its author:

<http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html>

I found your code a little baroque, so I wrote what I think is a simpler
example. Notice I never actually check the interrupt flag, but the code
terminates fine. If you comment out the call to interrupt(), then the
program does not terminate.

package quicktest;

/**
* @author Brenden Towey
*/
public class ThreadInterrupt
{
public static void main( String[] args ) throws Exception
{
Thread t = new Thread( new Wait() );
t.start();
Thread.sleep( 50 ); // wait a bit
t.interrupt();
t.join();
System.out.println( "Done!" );
}

private static class Wait implements Runnable {
@Override public synchronized void run() {
try { wait(); }
catch ( InterruptedException ex ) {}
}
}
}

OTOH hand if your library never makes any calls that do check for the
interrupt flag, well I'm pretty sure there's no chance of this working.
I'd still really prefer you find a way to make it work though; you're
spending a lot of time here to implement something that is fundamentally
broken (i.e., Thread.stop()).
 
T

taqmcg

Several low level APIs in Java check for the interrupt flag, so if your
library is calling these methods, it will check for interrupts implicitly..
Object.wait(), Thread.sleep(), most of the IO library, probably some
more which I don't recall at the moment.

Also, if you're going to be dealing with threads at all, get yourself a
copy of Java Concurrency in Practice. It's *the* state of the art for
working with threads in Java.

I'll also link to this article by its author:



<http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html>

It's an interesting article, but I think it tends to undercut your thesis that the check for interrupt in some basic calls [I don't think most normal I/O calls are included though, just some NIO ones] means that we don't needto couple the monitoring code and the worker thread. Since InterruptedException is a declared exception, we need to either declare it in any method that calls these, or we need to handle it in some way -- that's what Goetz is basically talking about. If you want to handle thread interrupts then you will often need to do more than swallow the interrupted exception. Just for grins, if we consider your worker thread as having three lines of code try, wait and catch, 66% of the worker code had to deal with handling the interrupt -- not especially decoupled.
OTOH hand if your library never makes any calls that do check for the
interrupt flag, well I'm pretty sure there's no chance of this working.
I'd still really prefer you find a way to make it work though; you're
spending a lot of time here to implement something that is fundamentally
broken (i.e., Thread.stop()).

Which brings us back to my original question: In what way is it 'fundamentally' broken? That suggests that there is something inherently unsafe and unfixable in all circumstances not just dangerous and easily misused.

Your right though that I need to get the book...

Regards,
Tom McGlynn
 
T

taqmcg

Yes .... I think I'm still not quite getting your point about effects
*before* Thread.stop() is called, but I don't know that it's very
important anyway.

Well that was mainly intended to be humorous, but it is important to understand how 'time' flows in the threads. We don't need to do anything special
until after we've invoked Thread.stop and at least in the two thread case both threads can easily know when to begin being careful.
I think the point I might have been overlooking is that you're
proposing to be very careful not to use any objects potentially
modified by the stopped thread, and given that, maybe my concern
about whether their state is visible to other threads is a red
herring.
....

B. L. Massingill

Right. That's one suggestion for how we might do things safely. That seems feasible to me, even natural. Typically my threads just do one thing that creates some object. If I discard the thread, I can ignore what it was starting to create.

Regards,
Tom McGlynn
 
L

Lew

markspace said:
Also, if you're going to be dealing with threads at all, get yourself a
copy of Java Concurrency in Practice. It's *the* state of the art for
working with threads in Java.

It's an interesting article, but I think it tends to undercut your thesisthat the check for interrupt in some basic calls [I don't think most normal I/O calls are included though, just some NIO ones] means that we don't need to couple the monitoring code and the worker thread. Since InterruptedException is a declared exception, we need to either declare it in any method that calls these, or we need to handle it in some way -- that's what Goetz is basically talking about. If you want to handle thread interrupts then you will often need to do more than swallow the interrupted exception. Just for grins, if we consider

Goetz and others point out that you should never swallow InterruptedException, but re-interrupt the
thread after handling it.
 
T

taqmcg

markspace wrote:
Also, if you're going to be dealing with threads at all, get yourself a
copy of Java Concurrency in Practice. It's *the* state of the art for
working with threads in Java.
It's an interesting article, but I think it tends to undercut your thesis that the check for interrupt in some basic calls [I don't think most normal I/O calls are included though, just some NIO ones] means that we don't need to couple the monitoring code and the worker thread. Since InterruptedException is a declared exception, we need to either declare it in any method that calls these, or we need to handle it in some way -- that's what Goetz is basically talking about. If you want to handle thread interrupts then you will often need to do more than swallow the interrupted exception. Just for grins, if we consider



Goetz and others point out that you should never swallow InterruptedException, but re-interrupt the

Never is a bit too strong. The referenced article indicates that there is one circumstance under which it's OK to swallow the interrupt -- where the thread is about to terminate. That's actually the case in the example Markgave which swallows the exception. But overall that right and it just emphasizes the point that reliance upon the fact that a few methods will throwan InterruptedException doesn't go very far in getting a thread to terminate.

I did get a chance to look at Java Concurrency in Practice. It doesn't talk about Thread.stop except in a footnote that says not to use it. But the only justification given is a reference to the very text that I found to beunconvincing at the start of this thread. Their view of this isn't surprising. I suspect these are the very people whose input led the class to be deprecated in the first place -- they may have written that text! [This doesn't in any way mean to 'deprecate' their comment, just to note that it's likely not an independent statement of the badness of Thread.stop from the deprecation itself.]

Nonetheless there are some interesting tidbits to be gleaned from the theirchapter on terminating threads that might be relevant to this discussion.

Overall in discussing thread interrupts they note that one needs to set up a policy for handling interrupts. The whole chapter is addressing policiesfor how to handle interrupts and other terminations. That same would surely be true for Thread.stop. It could only be used robustly within some clear policy.

They dismiss the need for preemptive termination of threads with:
"The cooperative approach is required because we rarely want a task, thread, or service to stop immediately, since that could leave shared data structures in an inconsistent state." This suggests that a stop policy might include: "we want the thread stopped immediately, and we have no further interest in any shared any data structures".

Finally, in their discussion of the handling of exceptions thrown in threads, they note that task processing threads are the only places where it is appropriate for RunTimeExceptions to be handled. We have yet another footnote:

"There is some controversy over the safety of this technique; when a threadthrows an unchecked exception, the entire application may possibly
be compromised. But the alternative, shutting down the entire application, is usually not practical."

As discussed very early in this thread, it seems like handling Thread.stop is very similar to handling RuntimeExceptions. It's not coincidental that task managers are the primary area in which I could see Thread.stop being used effectively. If one is capable of handling a RuntimeException in a thread, it may not be much different handling Thread.stop.

Regards,
Tom McGlynn
 

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,744
Messages
2,569,479
Members
44,900
Latest member
Nell636132

Latest Threads

Top