Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #24854 > unrolled thread

What is so bad aboud Thread.stop() ?

Started bytaqmcg@gmail.com
First post2013-07-31 06:36 -0700
Last post2013-08-15 12:12 -0700
Articles 20 on this page of 45 — 14 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  What is so bad aboud Thread.stop() ? taqmcg@gmail.com - 2013-07-31 06:36 -0700
    Re: What is so bad aboud Thread.stop() ? Marcel Müller <news.5.maazl@spamgourmet.org> - 2013-07-31 18:31 +0200
    Re: What is so bad aboud Thread.stop() ? Arne Vajhøj <arne@vajhoej.dk> - 2013-07-31 12:35 -0400
      Re: What is so bad aboud Thread.stop() ? Lew <lewbloch@gmail.com> - 2013-07-31 14:13 -0700
        Re: What is so bad aboud Thread.stop() ? usvirtualobservatory@gmail.com - 2013-08-01 07:38 -0700
          Re: What is so bad aboud Thread.stop() ? Lew <lewbloch@gmail.com> - 2013-08-01 14:07 -0700
            Re: What is so bad aboud Thread.stop() ? Steven Simpson <ss@domain.invalid> - 2013-08-01 23:15 +0100
              Re: What is so bad aboud Thread.stop() ? taqmcg@gmail.com - 2013-08-01 16:16 -0700
                Re: What is so bad aboud Thread.stop() ? "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> - 2013-08-02 18:35 +0100
                  Re: What is so bad aboud Thread.stop() ? Kevin McMurtrie <mcmurtrie@pixelmemory.us> - 2013-08-03 19:21 -0700
                Re: What is so bad aboud Thread.stop() ? Arne Vajhøj <arne@vajhoej.dk> - 2013-08-02 21:58 -0400
                  Re: What is so bad aboud Thread.stop() ? taqmcg@gmail.com - 2013-08-03 05:08 -0700
    Re: What is so bad aboud Thread.stop() ? Kevin McMurtrie <mcmurtrie@pixelmemory.us> - 2013-07-31 21:09 -0700
      Re: What is so bad aboud Thread.stop() ? usvirtualobservatory@gmail.com - 2013-08-01 08:00 -0700
        Re: What is so bad aboud Thread.stop() ? Arne Vajhøj <arne@vajhoej.dk> - 2013-08-01 11:25 -0400
          Re: What is so bad aboud Thread.stop() ? Eric Sosman <esosman@comcast-dot-net.invalid> - 2013-08-01 11:49 -0400
            Re: What is so bad aboud Thread.stop() ? Arne Vajhøj <arne@vajhoej.dk> - 2013-08-02 21:51 -0400
          Re: What is so bad aboud Thread.stop() ? taqmcg@gmail.com - 2013-08-01 09:30 -0700
            Re: What is so bad aboud Thread.stop() ? markspace <markspace@nospam.nospam> - 2013-08-01 10:01 -0700
            Re: What is so bad aboud Thread.stop() ? Arne Vajhøj <arne@vajhoej.dk> - 2013-08-02 21:55 -0400
    Re: What is so bad aboud Thread.stop() ? Sven Köhler <remove-sven.koehler@gmail.com> - 2013-08-01 18:28 +0300
    Re: What is so bad aboud Thread.stop() ? "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> - 2013-08-02 18:50 +0100
      Re: What is so bad aboud Thread.stop() ? taqmcg@gmail.com - 2013-08-02 11:34 -0700
        Re: What is so bad aboud Thread.stop() ? Arne Vajhøj <arne@vajhoej.dk> - 2013-08-02 22:04 -0400
          Re: What is so bad aboud Thread.stop() ? "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> - 2013-08-03 10:10 +0100
        Re: What is so bad aboud Thread.stop() ? "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> - 2013-08-03 10:28 +0100
          Re: What is so bad aboud Thread.stop() ? taqmcg@gmail.com - 2013-08-03 05:00 -0700
            Re: What is so bad aboud Thread.stop() ? blmblm@myrealbox.com <blmblm.myrealbox@gmail.com> - 2013-08-11 17:46 +0000
              Re: What is so bad aboud Thread.stop() ? taqmcg@gmail.com - 2013-08-13 11:47 -0700
                Re: What is so bad aboud Thread.stop() ? blmblm@myrealbox.com <blmblm.myrealbox@gmail.com> - 2013-08-13 20:18 +0000
                  Re: What is so bad aboud Thread.stop() ? Patricia Shanahan <pats@acm.org> - 2013-08-13 13:51 -0700
                    Re: What is so bad aboud Thread.stop() ? blmblm@myrealbox.com <blmblm.myrealbox@gmail.com> - 2013-08-14 22:42 +0000
                  Re: What is so bad aboud Thread.stop() ? taqmcg@gmail.com - 2013-08-13 14:10 -0700
                    Re: What is so bad aboud Thread.stop() ? Lew <lewbloch@gmail.com> - 2013-08-13 15:22 -0700
                      Re: What is so bad aboud Thread.stop() ? Arivald <NOSPAMarivald@interia.pl> - 2013-08-14 01:08 +0200
                        Re: What is so bad aboud Thread.stop() ? markspace <markspace@nospam.nospam> - 2013-08-13 16:45 -0700
                          Re: What is so bad aboud Thread.stop() ? Arivald <NOSPAMarivald@interia.pl> - 2013-08-14 08:42 +0200
                        Re: What is so bad aboud Thread.stop() ? Marcel Müller <news.5.maazl@spamgourmet.org> - 2013-08-14 09:48 +0200
                      Re: What is so bad aboud Thread.stop() ? taqmcg@gmail.com - 2013-08-14 08:55 -0700
                        Re: What is so bad aboud Thread.stop() ? markspace <markspace@nospam.nospam> - 2013-08-14 19:10 -0700
                          Re: What is so bad aboud Thread.stop() ? taqmcg@gmail.com - 2013-08-15 06:51 -0700
                            Re: What is so bad aboud Thread.stop() ? Lew <lewbloch@gmail.com> - 2013-08-15 17:35 -0700
                              Re: What is so bad aboud Thread.stop() ? taqmcg@gmail.com - 2013-08-16 06:30 -0700
                    Re: What is so bad aboud Thread.stop() ? blmblm@myrealbox.com <blmblm.myrealbox@gmail.com> - 2013-08-14 22:43 +0000
                      Re: What is so bad aboud Thread.stop() ? taqmcg@gmail.com - 2013-08-15 12:12 -0700

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#24870

FromSven Köhler <remove-sven.koehler@gmail.com>
Date2013-08-01 18:28 +0300
Message-ID<b5vd45F8blbU1@mid.dfncis.de>
In reply to#24854

On 31/07/13 16:36, taqmcg@gmail.com wrote:
> The use of Thread.stop() is strongly deprecated, but I'm a bit
> confused by the explanation given in the documentation: (e.g.,
> http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html)
>
>  Because it is inherently unsafe. Stopping a thread causes it to
> unlock all the monitors that it has locked. (The monitors are
> unlocked as the ThreadDeath exception propagates up the stack.) If
> any of the objects previously protected by these monitors were in an
> inconsistent state, other threads may now view these objects in an
> inconsistent state. Such objects are said to be damaged. When threads
> operate on damaged objects, arbitrary behavior can result. This
> behavior may be subtle and difficult to detect, or it may be
> pronounced. Unlike other unchecked exceptions, ThreadDeath kills
> threads silently; thus, the user has no warning that his program may
> be corrupted. The corruption can manifest itself at any time after
> the actual damage occurs, even hours or days in the future.
>
> As I understand this, the ThreadDeath exception is treated exactly as
> any other exception -- finally blocks are honored, it can even be
> caught -- that might be thrown unexpectedly.

A method that aquires a monitor usually performs a complex task. 
Consider the removal of an element from a double-linked list for 
example. A method deleting an element would first aquire the monitor, 
then manipulate a few references, at least two. And that is simply not 
atomic. If the ThreadDeath exception is thrown after the first reference 
has been adjusted but before the second reference has been adjusted, 
then the integrity of the list is broken. You wouldn't want that to 
happen, would you? The result can be arbitrary behaviour when this list 
is subquently used.

I have not seen anybody coding in a such way, that he anticipated a 
ThreadDeath exception in every line of a synchronized block. In 
particular, I never saw the finally block that would be needed to 
restore the integrity of the list (or whatever object the method is 
working on) in case of such an exception. And I would argue, that it's 
very tricky to do too!

> E.g., if we got an
> OutOfMemoryError or we happen to  explicitly throw a RuntimeException
> we're going to see exactly the same behavior with monitors released
> progressively as we go up the stack.  It's certainly easy enough  to
> catch and rethrow the ThreadDeath in its run method if I really want
> to log it and address the one difference.

I would assume, that an OutOfMemoryError thrown in the wrong line can 
actually result in an object's integrity being broken as well. Have you 
ever programmed in such a way, that the integrity of any object will not 
be harmed by an unexpected OutOfMemoryError? Or are you, like anybody 
else, praying that it never happens?



Regards,
   Sven

[toc] | [prev] | [next] | [standalone]


#24880

From"Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org>
Date2013-08-02 18:50 +0100
Message-ID<w8SdneFLYoQ8bGbMnZ2dnUVZ8jKdnZ2d@bt.com>
In reply to#24854
taqmcg@gmail.com wrote:
> The use of Thread.stop() is strongly deprecated, but I'm a bit confused
> by the explanation given in the documentation: (e.g.,
>[...]
> So what is the big hullaballoo about?

I suspect (modulo my other suspicion that you can't rely on exactly what 
Thread.stop() actually does in an actual implementation) that /if/ there is no 
mutable state shared with the rest of the program, then it might be OK.

Problem is: there's not a lot of point in a thread that shares /no/ state with 
the rest of the program.  If it's doing some computation (your? example of an 
untrusted regexp engine for instance) then it has to get the answer back to the 
calling thread somehow, and that is problematic.  Maybe there are some simple 
(in the sense of unsophisticated) mechanisms -- the calling thread polling a 
volatile variable perhaps (though I have doubts about the semantics of that: 
does reading a volatile variable guarantee that the data /referenced/ by that 
variable are consistent ?  My reading of the JLS doesn't find an answer to that 
question). But, say, stop()-ing a thread that is writing to a shared queue is a 
no-no.

/If/ you know that the thread is in a fixed, stable, state then you can 
probably kill it (assuming the state is suitable), but what about the 
end-points -- just as it is entering or leaving that state.  I find it 
difficult to imagine how you could be sure, avoiding race conditions, that it 
would be safe to stop() the thread unless your architecture was already such 
that implementing an alternative method wouldn't be easier (or at least, no 
harder -- and easier to justify to your peers ;-)

    -- chris 

[toc] | [prev] | [next] | [standalone]


#24881

Fromtaqmcg@gmail.com
Date2013-08-02 11:34 -0700
Message-ID<271335f6-4f91-4f2a-bf64-6925be460c8e@googlegroups.com>
In reply to#24880
On Friday, August 2, 2013 1:50:02 PM UTC-4, Chris Uppal wrote:
> taqmcg@gmail.com wrote:
> 
> > The use of Thread.stop() is strongly deprecated, but I'm a bit confused
> > by the explanation given in the documentation: (e.g.,
> >[...]
> > So what is the big hullaballoo about?
> 
> 
> I suspect (modulo my other suspicion that you can't rely on exactly what 
> Thread.stop() actually does in an actual implementation) that /if/ there is no 
> mutable state shared with the rest of the program, then it might be OK.
> Problem is: there's not a lot of point in a thread that shares /no/ state with 
> the rest of the program.  If it's doing some computation (your? example of an 
> untrusted regexp engine for instance) then it has to get the answer back to the 
> calling thread somehow, and that is problematic.  Maybe there are some simple 
> (in the sense of unsophisticated) mechanisms -- the calling thread polling a 
> volatile variable perhaps (though I have doubts about the semantics of that: 
> does reading a volatile variable guarantee that the data /referenced/ by that 
> variable are consistent ?  My reading of the JLS doesn't find an answer to that 
> question). But, say, stop()-ing a thread that is writing to a shared queue is a 
> no-no.
> 

I don't think you need to do anything particularly dramatic or even necessarily unusual to make separate out the thread-that-may-be-stopped's objects from the general ruck.  E.g., while the thread is running it works only on objects it creates. Only when it finishes successfully does the monitor thread use its results.  If the thread fails, they are just tossed out.  I don't think there is a problem with the stoppable thread having readonly access to data shared with the monitor.  You might get some kind of deadlock issue, but that's just general multithreading.  Should it have a lock on a shared object when it is killed, then if it has only readonly access, it won't be leaving the locked object in a damaged state when the monitor is released. [AFAICT]

> 
> /If/ you know that the thread is in a fixed, stable, state then you can 
> probably kill it (assuming the state is suitable), but what about the 
> end-points -- just as it is entering or leaving that state.  I find it 
> difficult to imagine how you could be sure, avoiding race conditions, that it 
> would be safe to stop() the thread unless your architecture was already such 
> that implementing an alternative method wouldn't be easier (or at least, no 
> harder -- and easier to justify to your peers ;-)

Does the thread need to be fixed or stable?  I <think> I only need to have it isolated.  That's part of what I'm trying to find out.  And unless and until I kill it, I can communicate with it using any standard method for interthread communication (e.g., shared objects).  That is much more difficult were I using a separate JVM as some have suggested.

You mention elsewhere that you're concerned that Thread.stop() might be only partially or imperfectly implemented.  That would certainly be an issue.  That would be the kind of 'magical' issue that a programmer simply can't get around.  However the documentation I've seen suggests that it is the danger of the method, not the quality of the implementation that is an issue.  

In any case, it certainly seems like the deprecation has done its job of keeping people from trying it out!

   Regards,
   Tom

[toc] | [prev] | [next] | [standalone]


#24885

FromArne Vajhøj <arne@vajhoej.dk>
Date2013-08-02 22:04 -0400
Message-ID<51fc654c$0$298$14726298@news.sunsite.dk>
In reply to#24881
On 8/2/2013 2:34 PM, taqmcg@gmail.com wrote:
> In any case, it certainly seems like the deprecation has done its job
> of keeping people from trying it out!

True.

People are also discarding assembler for their web application without
actually trying it out.

Most developers get paid to solve a business problem. If there is a
simple fast way of doing that and a unknown risky way, then you pick
the simple fast way every time and move on. They do not get paid to
spend a lot of time researching why, how much and in what cases
something is bad.

Arne

[toc] | [prev] | [next] | [standalone]


#24889

From"Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org>
Date2013-08-03 10:10 +0100
Message-ID<EeidndijnIp4V2HMnZ2dnUVZ8tKdnZ2d@bt.com>
In reply to#24885
Arne Vajhøj wrote:

> They do not get paid to
> spend a lot of time researching why, how much and in what cases
> something is bad.

Doesn't mean that they aren't paid to /think/.

Questioning (not /rejecting/) recieved wisdom is part of that.

I would not care to hire, nor even use software written by, someone who didn't 
want to know the whys.

And anyway, I doubt if anyone here is being paid to take part in this 
discussion.

    -- chris 

[toc] | [prev] | [next] | [standalone]


#24890

From"Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org>
Date2013-08-03 10:28 +0100
Message-ID<xoednYWz9K2jUGHMnZ2dnUVZ8m-dnZ2d@bt.com>
In reply to#24881
taqmcg@gmail.com wrote:

> unless and until I kill it, I can communicate with it using any standard
> method for interthread communication (e.g., shared objects).

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 to make
/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.

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 ?

    -- chris


[toc] | [prev] | [next] | [standalone]


#24891

Fromtaqmcg@gmail.com
Date2013-08-03 05:00 -0700
Message-ID<ede0c691-85eb-4977-8644-27078248ed9d@googlegroups.com>
In reply to#24890
On Saturday, August 3, 2013 5:28:41 AM UTC-4, Chris Uppal wrote:
> taqmcg@gmail.com wrote:
> 
> 
> 
> > unless and until I kill it, I can communicate with it using any standard
> > method for interthread communication (e.g., shared objects).
> 
> 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 to make
> /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't mean 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.

> 
>     -- chris

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

[toc] | [prev] | [next] | [standalone]


#24952

Fromblmblm@myrealbox.com <blmblm.myrealbox@gmail.com>
Date2013-08-11 17:46 +0000
Message-ID<b6q109Fsua7U1@mid.individual.net>
In reply to#24891
In article <ede0c691-85eb-4977-8644-27078248ed9d@googlegroups.com>,
 <taqmcg@gmail.com> wrote:
> On Saturday, August 3, 2013 5:28:41 AM UTC-4, Chris Uppal wrote:
> > taqmcg@gmail.com wrote:
> > 
> > 
> > 
> > > unless and until I kill it, I can communicate with it using any standard
> > > method for interthread communication (e.g., shared objects).
> > 
> > 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 to make
> > /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'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?

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

-- 
B. L. Massingill
ObDisclaimer:  I don't speak for my employers; they return the favor.

[toc] | [prev] | [next] | [standalone]


#24954

Fromtaqmcg@gmail.com
Date2013-08-13 11:47 -0700
Message-ID<7cb96188-91ce-4c2b-ace8-5eeb1b30815e@googlegroups.com>
In reply to#24952
On Sunday, August 11, 2013 1:46:49 PM UTC-4, blmblm @ myrealbox. com wrote:
> In article <ede0c691-85eb-4977-8644-27078248ed9d@googlegroups.com>,
> 
>  <taqmcg@gmail.com> wrote:
> 
> ...
> > 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?
> 
> 
> 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

[toc] | [prev] | [next] | [standalone]


#24955

Fromblmblm@myrealbox.com <blmblm.myrealbox@gmail.com>
Date2013-08-13 20:18 +0000
Message-ID<b6vilcF4judU1@mid.individual.net>
In reply to#24954
In article <7cb96188-91ce-4c2b-ace8-5eeb1b30815e@googlegroups.com>,
 <taqmcg@gmail.com> wrote:
> On Sunday, August 11, 2013 1:46:49 PM UTC-4, blmblm @ myrealbox. com wrote:
> > In article <ede0c691-85eb-4977-8644-27078248ed9d@googlegroups.com>,
> > 
> >  <taqmcg@gmail.com> wrote:
> > 
> > ...
> > > 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?
> > 
> > 
> > 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.


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


> 
>     Tom McGlynn
> 
> 
> might be killed in the future could affect it before I kill it
> 

-- 
B. L. Massingill
ObDisclaimer:  I don't speak for my employers; they return the favor.

[toc] | [prev] | [next] | [standalone]


#24956

FromPatricia Shanahan <pats@acm.org>
Date2013-08-13 13:51 -0700
Message-ID<f-udnfhoIIPHAZfPnZ2dnUVZ_smdnZ2d@earthlink.com>
In reply to#24955
On 8/13/2013 1:18 PM, blmblm@myrealbox.com wrote:
...
> 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.)
...

"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

Patricia



[toc] | [prev] | [next] | [standalone]


#24980

Fromblmblm@myrealbox.com <blmblm.myrealbox@gmail.com>
Date2013-08-14 22:42 +0000
Message-ID<b72ff4Fnlp4U1@mid.individual.net>
In reply to#24956
In article <f-udnfhoIIPHAZfPnZ2dnUVZ_smdnZ2d@earthlink.com>,
Patricia Shanahan  <pats@acm.org> wrote:
> On 8/13/2013 1:18 PM, blmblm@myrealbox.com wrote:
> ...
> > 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.)
> ...
> 
> "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. L. Massingill
ObDisclaimer:  I don't speak for my employers; they return the favor.

[toc] | [prev] | [next] | [standalone]


#24957

Fromtaqmcg@gmail.com
Date2013-08-13 14:10 -0700
Message-ID<5f47910f-5450-4578-818c-cac2d4b6f436@googlegroups.com>
In reply to#24955
On Tuesday, August 13, 2013 4:18:52 PM UTC-4, blmblm @ myrealbox. com wrote:
> In article <7cb96188-91ce-4c2b-ace8-5eeb1b30815e@googlegroups.com>,
> 
>  <taqmcg@gmail.com> wrote:
> 
> > On Sunday, August 11, 2013 1:46:49 PM UTC-4, blmblm @ myrealbox. com wrote:
> 
> > > In article <ede0c691-85eb-4977-8644-27078248ed9d@googlegroups.com>,
> 
> > > 
> > >  <taqmcg@gmail.com> wrote:
> > > 
> > > ...
> > > > 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?
> > > 
> > > 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.
> 
> 
> 
> 
> 
> 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.)
> 
> 
> >     Tom McGlynn
> 
> 
> 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 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.

  Regards,
  Tom McGlynn

[toc] | [prev] | [next] | [standalone]


#24958

FromLew <lewbloch@gmail.com>
Date2013-08-13 15:22 -0700
Message-ID<39a5e684-7cf8-4f00-ba3b-7e280b19d669@googlegroups.com>
In reply to#24957
taq...@gmail.com wrote:
> 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.

-- 
Lew

[toc] | [prev] | [next] | [standalone]


#24959

FromArivald <NOSPAMarivald@interia.pl>
Date2013-08-14 01:08 +0200
Message-ID<kueeec$290$1@news.dialog.net.pl>
In reply to#24958
W dniu 2013-08-14 00:22, Lew pisze:
> taq...@gmail.com wrote:
>> 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.
>

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/

-- 
Arivald

[toc] | [prev] | [next] | [standalone]


#24960

Frommarkspace <markspace@nospam.nospam>
Date2013-08-13 16:45 -0700
Message-ID<kueged$l29$1@dont-email.me>
In reply to#24959
On 8/13/2013 4:08 PM, Arivald wrote:

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

[toc] | [prev] | [next] | [standalone]


#24967

FromArivald <NOSPAMarivald@interia.pl>
Date2013-08-14 08:42 +0200
Message-ID<kuf91j$daf$1@news.dialog.net.pl>
In reply to#24960
W dniu 2013-08-14 01:45, markspace pisze:
> On 8/13/2013 4:08 PM, Arivald wrote:
>
>> 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.
>
>

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.

-- 
Arivald

[toc] | [prev] | [next] | [standalone]


#24969

FromMarcel Müller <news.5.maazl@spamgourmet.org>
Date2013-08-14 09:48 +0200
Message-ID<520b3649$0$6570$9b4e6d93@newsspool4.arcor-online.net>
In reply to#24959
On 14.08.13 01.08, Arivald wrote:
> 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

[toc] | [prev] | [next] | [standalone]


#24976

Fromtaqmcg@gmail.com
Date2013-08-14 08:55 -0700
Message-ID<b343ce47-aeff-408b-943e-9bba4b280504@googlegroups.com>
In reply to#24958
On Tuesday, August 13, 2013 6:22:33 PM UTC-4, Lew wrote:
> taq...@gmail.com wrote:
> 
> > 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.
> 
> -- 
> 
> Lew

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 a set of worker threads.  Each worker thread requests a task from the monitor, executes the task, reports the result back to the monitor, then asks for the next task.  The monitor periodically kills all threads older than some arbitrary 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's not 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 fair test 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 that programs 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'll close 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 invoking threads 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

[toc] | [prev] | [next] | [standalone]


#24995

Frommarkspace <markspace@nospam.nospam>
Date2013-08-14 19:10 -0700
Message-ID<kuhdak$l7h$1@dont-email.me>
In reply to#24976
On 8/14/2013 8:55 AM, taqmcg@gmail.com wrote:

> 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()).

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.lang.java.programmer


csiph-web