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 1 of 3  [1] 2 3  Next page →


#24854 — What is so bad aboud Thread.stop() ?

Fromtaqmcg@gmail.com
Date2013-07-31 06:36 -0700
SubjectWhat is so bad aboud Thread.stop() ?
Message-ID<8fe57dc2-a323-4821-941c-4036663cbce5@googlegroups.com>
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.  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.

So what is the big hullaballoo about?  Is there something special going on here with Thread.stop(), or is this just a specific instance of the fact the we should be very careful whenever a thread has been stopped by an unexpected exception?

Thread.stop() might be called at any time in the to-be-stopped thread, and that might be an issue, but at least in principle the thread that issues the stop could check the to-be-stopped thread and only stop it at 'appropriate' points where appropriate is defined by the user.  

E.g., suppose I have some concern that a piece of code that I'm about to run might have an infinite loop in it (say I'm testing somebody else's regular expression parser with lots of different RE's), but it's not going to allocate any external resources (e.g., files, DB connections).  I could set/clear a flag as I enter and leave the suspect code.  Could I safely monitor this thread in another thread.  After say 100 seconds if a given expression hasn't parsed can the monitor thread invoke a Thread.stop() safely if my flag shows that the RE thread is caught in the parser?

Thanks for your insight.
     Regards,
     Tom MCglynn

[toc] | [next] | [standalone]


#24856

FromMarcel Müller <news.5.maazl@spamgourmet.org>
Date2013-07-31 18:31 +0200
Message-ID<51f93bdd$0$6559$9b4e6d93@newsspool4.arcor-online.net>
In reply to#24854
On 31.07.13 15.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)

Do you know about race conditions in multi-threaded programming?
Thread.stop() can cause race conditions because it interrupts the thread 
at any arbitrary location. So code that is executed under protection of 
a mutex (=monitor) can be forced to release the mutex without a chance 
to complete its work. This breaks the happens-before relation that the 
mutex introduced.

Think of the following pseudo instruction sequence.

// interrupted thread
1. mutex.enter();
2. staticVar = new MyClass();
3. staticVar.setParent(some_parent_window);
4. mutex.exit();

// other thread
1. mutex.enter();
2. if (staticVar == null) continue at step 5
3. MyClass parent = staticVar.getParent();
4. do_somthing_with(parent);
5. mutex.exit();

This fragment is perfectly valid under normal conditions but it has a 
race condition if the first thread can be stopped. If it happens that 
the first thread is stopped after step 2 then the class referred by 
staticVar might only be partially initialized, because Thread.stop 
forces the execution of step 4 but not step 3. This causes the other 
thread to fail badly because it may use a null reference at its step 4.

Indeed, strictly speaking the above code is not exception safe. I 
setParent() throws the result is the same. But most real world code is 
not exception safe (at any point). Simply because trivial functions like 
getters usually don't throw. In Java most exceptions therefore can't be 
thrown without declaration.

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

True, but no one expects a program to do anything reasonable after an 
out of memory exception. Most likely Java does not reasonable recover 
from that anyway, because subsequent new operators are likely to fail too.

> E.g., suppose I have some concern that a piece of code that I'm about to run might have an infinite loop in it (say I'm testing somebody else's regular expression parser with lots of different RE's), but it's not going to allocate any external resources (e.g., files, DB connections).  I could set/clear a flag as I enter and leave the suspect code.  Could I safely monitor this thread in another thread.  After say 100 seconds if a given expression hasn't parsed can the monitor thread invoke a Thread.stop() safely if my flag shows that the RE thread is caught in the parser?

You could do that under certain conditions.

First accessing any side effects of the interrupted code (like static 
vars or modified objects) might result in undefined behavior. You might 
ensure this in your case.

Secondly the executing code must not have spawned own threads e.g. for 
using more than one CPU core. This cannot be more than a convention, 
because you never know what the used libraries do behind the scenes. 
E.g. calling an FFT-library might result in parallel threads. It may 
also schedule the computing to the graphics hardware if the hardware and 
the drivers are suitable for that.

So for testing purposes a separate task is significantly safer. Of 
course, if you are testing your own code and you know what you are 
doing, just use Thread.stop. Hey, it's just a test case, and if it 
succeeds Thread.stop has never been called, so this result is reliable. 
But further tests in the same run /might/ not be reliable anymore if you 
aborted the test.


Marcel

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


#24857

FromArne Vajhøj <arne@vajhoej.dk>
Date2013-07-31 12:35 -0400
Message-ID<51f93cc4$0$291$14726298@news.sunsite.dk>
In reply to#24854
On 7/31/2013 9:36 AM, 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.  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.
>
> So what is the big hullaballoo about?  Is there something special
> going on here with Thread.stop(), or is this just a specific instance
> of the fact the we should be very careful whenever a thread has been
> stopped by an unexpected exception?
>
> Thread.stop() might be called at any time in the to-be-stopped
> thread, and that might be an issue, but at least in principle the
> thread that issues the stop could check the to-be-stopped thread and
> only stop it at 'appropriate' points where appropriate is defined by
> the user.
>
> E.g., suppose I have some concern that a piece of code that I'm about
> to run might have an infinite loop in it (say I'm testing somebody
> else's regular expression parser with lots of different RE's), but
> it's not going to allocate any external resources (e.g., files, DB
> connections).  I could set/clear a flag as I enter and leave the
> suspect code.  Could I safely monitor this thread in another thread.
> After say 100 seconds if a given expression hasn't parsed can the
> monitor thread invoke a Thread.stop() safely if my flag shows that
> the RE thread is caught in the parser?

I think this part is the critical part

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

There are cases where using it may result in problems.

There may also be cases where it will work fine. But that is
not sufficient to consider something "safe".

Go with the recommended approach of having the external
thread set a flag and the thread itself read it and close
down.

Arne

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


#24860

FromLew <lewbloch@gmail.com>
Date2013-07-31 14:13 -0700
Message-ID<a6efb240-0426-4019-896e-2f41cf74a26a@googlegroups.com>
In reply to#24857
Arne Vajhøj 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., 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

Do you know what they mean by a monitor?

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

Inconsistent state is bad.

>>    may now view these objects in an inconsistent state.
>>    Such objects are said to be damaged. When threads operate on

Damaged is bad.

>>    damaged objects, arbitrary behavior can result. This behavior

Arbitrary behavior is bad.

> >    may be subtle and difficult to detect, or it may be pronounced.

Subtle and difficult to detect is bad, really even worse than pronounced, because 
it confounds one's ability to fix it.

>>    Unlike other unchecked exceptions, ThreadDeath kills threads silently;

Killed silently is bad.

>>    thus, the user has no warning that his program may be corrupted.

No warning that the program is corrupted is bad.

>>    The corruption can manifest itself at any time after the actual
>>    damage occurs, even hours or days in the future.

Random timing of corruption is bad.

>> As I understand this, the ThreadDeath exception is treated exactly as
>> any other exception -- finally blocks are honored, it can even be

Except for the differences mentioned in the passage you cited.

>> caught -- that might be thrown unexpectedly.  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

Who said that 'Thread.stop()' release monitors progressively or goes up the stack?

>> catch and rethrow the ThreadDeath in its run method if I really want
>> to log it and address the one difference.

Who will catch the exception?

>> So what is the big hullaballoo about?  Is there something special

Broken code that fails silently at unexpected times in ways that are difficult to detect, 
let alone diagnose, that causes your program to be useless but you can't fix it.

>> going on here with Thread.stop(), or is this just a specific instance

Yes.

>> of the fact the we should be very careful whenever a thread has been
>> stopped by an unexpected exception?

Even if it were, it wouldn't merit the word "just".

>> Thread.stop() might be called at any time in the to-be-stopped
>> thread, and that might be an issue, but at least in principle the
>> thread that issues the stop could check the to-be-stopped thread and
>> only stop it at 'appropriate' points where appropriate is defined by
>> the user.

No, because the starting thread has no insight into where the started thread is, 
or what points are appropriate, except for critical sections, which are for shit when 
a 'stop()' call destroys things.

>> E.g., suppose I have some concern that a piece of code that I'm about
>> to run might have an infinite loop in it (say I'm testing somebody
>> else's regular expression parser with lots of different RE's), but
>> it's not going to allocate any external resources (e.g., files, DB
>> connections).  I could set/clear a flag as I enter and leave the
>> suspect code.  Could I safely monitor this thread in another thread.
>> After say 100 seconds if a given expression hasn't parsed can the
>> monitor thread invoke a Thread.stop() safely if my flag shows that
>> the RE thread is caught in the parser?

No.

> I think this part is the critical part
> 
> #    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.
> 
> There are cases where using it may result in problems.
> 
> There may also be cases where it will work fine. But that is
> not sufficient to consider something "safe".
> 
> Go with the recommended approach of having the external
> thread set a flag and the thread itself read it and close
> down.

Buy and closely study _Java Concurrency in Practice_ by Brian Goetz, et al. You will 
not get the in-depth understanding you need from a newsgroup.

-- 
Lew

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


#24867

Fromusvirtualobservatory@gmail.com
Date2013-08-01 07:38 -0700
Message-ID<699768ec-b0b7-4752-a373-b58b8a39e32e@googlegroups.com>
In reply to#24860
On Wednesday, July 31, 2013 5:13:25 PM UTC-4, Lew wrote:
...
> >> As I understand this, the ThreadDeath exception is treated exactly as
> 
> >> any other exception -- finally blocks are honored, it can even be
> 
> 
> 
> Except for the differences mentioned in the passage you cited.
> 

That's the crux of my confusion.  It is my understanding that the propagation
of the thread death is exactly the same as for any other exception.  So
ThreadDeath behaves exactly as any other exception that might be triggered.
The only difference is that it can get triggered anywhere.  None of the items
you have in litany of 'bad' things is different for other exceptions. 
> 
> 
> >> caught -- that might be thrown unexpectedly.  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
> 
> 
> 
> Who said that 'Thread.stop()' release monitors progressively or goes up the stack?

The text I quoted.  So Oracle (nee Sun).

> 
> 
> 
> >> catch and rethrow the ThreadDeath in its run method if I really want
> 
> >> to log it and address the one difference.
> 
> 
> 
> Who will catch the exception?
> 
The code being stopped.  E.g., I could have my
thread defined in a class Z like:

  class Z implements Runnable {
      public void run() {
          try {
               ... code
          } catch (ThreadDeath e) {
               log(e);
               throw e;
          }
      }
   }
> 
> 
> >> So what is the big hullaballoo about?  Is there something special
> 
> 
> 
> Broken code that fails silently at unexpected times in ways that are difficult to detect, 
> 
> let alone diagnose, that causes your program to be useless but you can't fix it.
> 
> 
> 
> >> going on here with Thread.stop(), or is this just a specific instance
> 
> 
> 
> Yes.

What is it that is special?
> 
> 
> 
> >> of the fact the we should be very careful whenever a thread has been
> 
> >> stopped by an unexpected exception?
> 
> 
....
> 
> 
> >> Thread.stop() might be called at any time in the to-be-stopped
> 
> >> thread, and that might be an issue, but at least in principle the
> 
> >> thread that issues the stop could check the to-be-stopped thread and
> 
> >> only stop it at 'appropriate' points where appropriate is defined by
> 
> >> the user.
> 
> 
> 
> No, because the starting thread has no insight into where the started thread is, 
> 
> or what points are appropriate, except for critical sections, which are for shit when 
> 
> a 'stop()' call destroys things.

But as the example shows its easy to arrange things so that the stopping
thread can know something.  Until I actually call Thread.stop, all the normal mechanisms by which thread's communicate can be invoked. Does it have to be fine grained in some way that can't be done using these? Why?

> 
> 
> 
> >> E.g., suppose I have some concern that a piece of code that I'm about
> 
> >> to run might have an infinite loop in it (say I'm testing somebody
> 
> >> else's regular expression parser with lots of different RE's), but
> 
> >> it's not going to allocate any external resources (e.g., files, DB
> 
> >> connections).  I could set/clear a flag as I enter and leave the
> 
> >> suspect code.  Could I safely monitor this thread in another thread.
> 
> >> After say 100 seconds if a given expression hasn't parsed can the
> 
> >> monitor thread invoke a Thread.stop() safely if my flag shows that
> 
> >> the RE thread is caught in the parser?
> 
> 
> 
> No.

Why not?  By hypothesis say there are no subthreads created, no files, no external connections.  I can ensure that no objects created in the RE code thread are going to be accessed by the monitor thread or any other -- at least in the code I control.  We're just going to throw them away.  What is it that will trip me up?


> 
> 
> 
> > I think this part is the critical part
> 
> > 
> 
> > #    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.
> 
> > 
> 
> > There are cases where using it may result in problems.
> 
> > 
> 
> > There may also be cases where it will work fine. But that is
> 
> > not sufficient to consider something "safe".
> 
> > 
> 
> > Go with the recommended approach of having the external
> 
> > thread set a flag and the thread itself read it and close
> 
> > down.
> 
> 
> 
> Buy and closely study _Java Concurrency in Practice_ by Brian Goetz, et al. You will 
> 
> not get the in-depth understanding you need from a newsgroup.
> 
> 
> 
> -- 
> 
> Lew

Maybe, but the discussion in a newsgroup can be quite informative.

Thanks for you comments,
   Tom


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


#24874

FromLew <lewbloch@gmail.com>
Date2013-08-01 14:07 -0700
Message-ID<d20ff1e2-ca8a-4b8e-bdbe-6e6f11b4d75c@googlegroups.com>
In reply to#24867
usvirtualo...@gmail.com wrote:
> Lew wrote:
>> Who will catch the exception?
> 
>The code being stopped.  E.g., I could have my
> thread defined in a class Z like:
> 
>   class Z implements Runnable {
>       public void run() {
>           try {
>                ... code
>           } catch (ThreadDeath e) {

Since this catch is in the same thread that just died, it cannot run.

>                log(e);
>                throw e;
>           }
>       }
>    }

-- 
Lew

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


#24877

FromSteven Simpson <ss@domain.invalid>
Date2013-08-01 23:15 +0100
Message-ID<s83rca-n0e.ln1@s.simpson148.btinternet.com>
In reply to#24874
On 01/08/13 22:07, Lew wrote:
> usvirtualo...@gmail.com wrote:
>> Lew wrote:
>>> Who will catch the exception?
>> The code being stopped.  E.g., I could have my
>> thread defined in a class Z like:
>>
>>    class Z implements Runnable {
>>        public void run() {
>>            try {
>>                 ... code
>>            } catch (ThreadDeath e) {
> Since this catch is in the same thread that just died, it cannot run.

Are you saying that this won't print out "Dead"?

   public class Stopped {
       public static void main(String[] args) throws Exception {
           Thread t = new Thread() {
                   public void run() {
                       try {
                           Thread.sleep(10000);
                       } catch (InterruptedException ex) {
                           System.out.println("Interrupted");
                       } catch (ThreadDeath td) {
                           System.out.println("Dead");
                       }
                   }
               };

           t.start();
           Thread.sleep(4000);
           System.out.println("Stopping");
           t.stop();
       }
   }

I get:

   Stopping
   Dead



-- 
ss at comp dot lancs dot ac dot uk

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


#24878

Fromtaqmcg@gmail.com
Date2013-08-01 16:16 -0700
Message-ID<16e55f41-fdc1-42d1-8819-f2d0ebcffb52@googlegroups.com>
In reply to#24877
On Thursday, August 1, 2013 6:15:23 PM UTC-4, Steven Simpson wrote:
> On 01/08/13 22:07, Lew wrote:
> 
> > usvirtualo...@gmail.com wrote:
> 
> >> Lew wrote:
> >>> Who will catch the exception?
> >> The code being stopped.  E.g., I could have my
> >> thread defined in a class Z like:
> >>
> >>    class Z implements Runnable {
> >>        public void run() {
> >>            try {
> >>                 ... code
> >>            } catch (ThreadDeath e) {
> > Since this catch is in the same thread that just died, it cannot run.
> 
> Are you saying that this won't print out "Dead"?
> 
>    public class Stopped {
>        public static void main(String[] args) throws Exception {
>            Thread t = new Thread() {
>                    public void run() {
>                        try {
>                            Thread.sleep(10000);
>                        } catch (InterruptedException ex) {
>                            System.out.println("Interrupted");
>                        } catch (ThreadDeath td) {
>                            System.out.println("Dead");
>                        }
>                    }
>                };
> 
>            t.start();
>            Thread.sleep(4000);
>            System.out.println("Stopping");
>            t.stop();
>        }
>    }
> 
> I get:
> 
>    Stopping
>    Dead


It's interesting that even one as well versed in Java as Lew seems to misunderstand how Thread.stop works.  An (admittedly non-authoritative) explanation is available at http://vanillajava.blogspot.com/2011/06/threadstop-really-stop-thread.html.  I think Lew shares the apprehension I had had that it does something magical and brings the thread down instantly, it seems clear that its behavior is dangerous but bounded.


   Tom

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


#24879

From"Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org>
Date2013-08-02 18:35 +0100
Message-ID<v_qdnar96e1XcGbMnZ2dnUVZ7tqdnZ2d@bt.com>
In reply to#24878
taqmcg@gmail.com wrote:

> I think Lew shares the apprehension I had had that it does something
> magical and brings the thread down instantly, it seems clear that its
> behavior is dangerous but bounded.

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 

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


#24897

FromKevin McMurtrie <mcmurtrie@pixelmemory.us>
Date2013-08-03 19:21 -0700
Message-ID<mcmurtrie-751FCF.19214903082013@c-61-68-245-199.per.connect.net.au>
In reply to#24879
In article <v_qdnar96e1XcGbMnZ2dnUVZ7tqdnZ2d@bt.com>,
 "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> wrote:

> taqmcg@gmail.com wrote:
> 
> > I think Lew shares the apprehension I had had that it does something
> > magical and brings the thread down instantly, it seems clear that its
> > behavior is dangerous but bounded.
> 
> 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.

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


#24884

FromArne Vajhøj <arne@vajhoej.dk>
Date2013-08-02 21:58 -0400
Message-ID<51fc63db$0$291$14726298@news.sunsite.dk>
In reply to#24878
On 8/1/2013 7:16 PM, taqmcg@gmail.com wrote:
> On Thursday, August 1, 2013 6:15:23 PM UTC-4, Steven Simpson wrote:
>> On 01/08/13 22:07, Lew wrote:
>>> usvirtualo...@gmail.com wrote:
>>>> Lew wrote:
>>>>> Who will catch the exception?
>>>> The code being stopped.  E.g., I could have my thread defined
>>>> in a class Z like:
>>>>
>>>> class Z implements Runnable { public void run() { try { ...
>>>> code } catch (ThreadDeath e) {
>>> Since this catch is in the same thread that just died, it cannot
>>> run.
>>
>> Are you saying that this won't print out "Dead"?
...
>> I get:
>>
>> Stopping Dead
>
>
> It's interesting that even one as well versed in Java as Lew seems to
> misunderstand how Thread.stop works.  An (admittedly
> non-authoritative) explanation is available at
> http://vanillajava.blogspot.com/2011/06/threadstop-really-stop-thread.html.
> I think Lew shares the apprehension I had had that it does something
> magical and brings the thread down instantly, it seems clear that its
> behavior is dangerous but bounded.

Lew is an experienced programmer.

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

Arne

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


#24892

Fromtaqmcg@gmail.com
Date2013-08-03 05:08 -0700
Message-ID<3ef0d996-5cd4-4e19-901b-001df031de88@googlegroups.com>
In reply to#24884
On Friday, August 2, 2013 9:58:46 PM UTC-4, Arne Vajhøj wrote:
> On 8/1/2013 7:16 PM, taqmcg@gmail.com wrote:
> 
> > On Thursday, August 1, 2013 6:15:23 PM UTC-4, Steven Simpson wrote:
>> 
> 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   

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


#24866

FromKevin McMurtrie <mcmurtrie@pixelmemory.us>
Date2013-07-31 21:09 -0700
Message-ID<51f9df70$0$52766$742ec2ed@news.sonic.net>
In reply to#24854
In article <8fe57dc2-a323-4821-941c-4036663cbce5@googlegroups.com>,
 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/threadPrimit
> iveDeprecation.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.  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.
> 
> So what is the big hullaballoo about?  Is there something special going on 
> here with Thread.stop(), or is this just a specific instance of the fact the 
> we should be very careful whenever a thread has been stopped by an unexpected 
> exception?
> 
> Thread.stop() might be called at any time in the to-be-stopped thread, and 
> that might be an issue, but at least in principle the thread that issues the 
> stop could check the to-be-stopped thread and only stop it at 'appropriate' 
> points where appropriate is defined by the user.  
> 
> E.g., suppose I have some concern that a piece of code that I'm about to run 
> might have an infinite loop in it (say I'm testing somebody else's regular 
> expression parser with lots of different RE's), but it's not going to 
> allocate any external resources (e.g., files, DB connections).  I could 
> set/clear a flag as I enter and leave the suspect code.  Could I safely 
> monitor this thread in another thread.  After say 100 seconds if a given 
> expression hasn't parsed can the monitor thread invoke a Thread.stop() safely 
> if my flag shows that the RE thread is caught in the parser?
> 
> Thanks for your insight.
>      Regards,
>      Tom MCglynn

The problem is that it causes an exception from code that can not throw 
an exception.  It corrupts the data in shared objects.  Example:

if (thing == null)
   throw new NullPointerException("thing must not be null");
data[++count]= thing;

This could be killed after incrementing 'count' but before assigning the 
array element.  Now you have a very illegal null element.
-- 
I will not see posts from Google because I must filter them as spam

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


#24868

Fromusvirtualobservatory@gmail.com
Date2013-08-01 08:00 -0700
Message-ID<7bf3ea0e-533b-4cfe-a85d-ad75b5d3657c@googlegroups.com>
In reply to#24866
On Thursday, August 1, 2013 12:09:20 AM UTC-4, Kevin McMurtrie wrote:
...
> The problem is that it causes an exception from code that can not throw 
> 
> an exception.  It corrupts the data in shared objects.  Example:
> 
> 
> 
> if (thing == null)
> 
>    throw new NullPointerException("thing must not be null");
> 
> data[++count]= thing;
> 
> 
> 
> This could be killed after incrementing 'count' but before assigning the 
> 
> array element.  Now you have a very illegal null element.
> 
> -- 
> 
> I will not see posts from Google because I must filter them as spam

[My apologies to Kevin who will not see this directly since I've only access
to GoogleGroups to post.]

While it's clear that one cannot continue on naively  after issuing a Thread.stop(), the question I'm trying to understand is whether it's feasible in some conditions to do so reasonably safely.  E.g., suppose I don't look at any of the objects that are create/modified in the stopped thread.  They are all thrown away.  Then the fact that they are potentially in a damaged state need not be an issue -- they will never be used again.  


But is there any system level magic that precludes doing this regardless of the care one takes?  E.g., maybe there are lots of internal globals in seemingly innocuous standard classes that get corrupted that are impossible to avoid, or there's an unavoidable chance that garbage collection will be broken, or ???

Or is it that in practice it's difficult to do this with sufficient care, but is in principle achievable? 

   Regards,
   Tom

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


#24869

FromArne Vajhøj <arne@vajhoej.dk>
Date2013-08-01 11:25 -0400
Message-ID<51fa7dea$0$298$14726298@news.sunsite.dk>
In reply to#24868
On 8/1/2013 11:00 AM, usvirtualobservatory@gmail.com wrote:
> On Thursday, August 1, 2013 12:09:20 AM UTC-4, Kevin McMurtrie wrote:
> ...
>> The problem is that it causes an exception from code that can not throw
>> an exception.  It corrupts the data in shared objects.  Example:
>>
>> if (thing == null)
>>     throw new NullPointerException("thing must not be null");
>> data[++count]= thing;
>>
>> This could be killed after incrementing 'count' but before assigning the
>>
>> array element.  Now you have a very illegal null element.

> While it's clear that one cannot continue on naively  after issuing a
> Thread.stop(), the question I'm trying to understand is whether it's
> feasible in some conditions to do so reasonably safely.  E.g.,
> suppose I don't look at any of the objects that are create/modified
> in the stopped thread.  They are all thrown away.  Then the fact that
> they are potentially in a damaged state need not be an issue -- they
> will never be used again.
>
> But is there any system level magic that precludes doing this
> regardless of the care one takes?  E.g., maybe there are lots of
> internal globals in seemingly innocuous standard classes that get
> corrupted that are impossible to avoid, or there's an unavoidable
> chance that garbage collection will be broken, or ???
>
> Or is it that in practice it's difficult to do this with sufficient
> care, but is in principle achievable?

I think it is something like:

You can achieve what you want to do in two ways:
A) use Thread.stop
B) set a flag and let the thread do what it need to do to
    terminate in a graceful manner

#A can be done safely in some cases and can not be done safely in
other cases. Even if it can be done safely, then it will require
significant analysis to get it right. And even if it gets done
right, then there is a high risk that that a bug will be introduced
during maintenance later, because the maintenance programmer do not
have the skill or the time to understand the subtleties of the
problem.

#B can always be done safely. It requires not much work. And
is relative maintenance friendly.

Easy choice in my opinion.

Arne


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


#24871

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2013-08-01 11:49 -0400
Message-ID<ktdvm7$bai$1@dont-email.me>
In reply to#24869
On 8/1/2013 11:25 AM, Arne Vajhøj wrote:
> [...]
> I think it is something like:
>
> You can achieve what you want to do in two ways:
> A) use Thread.stop
> B) set a flag and let the thread do what it need to do to
>     terminate in a graceful manner
>
> #A can be done safely in some cases and can not be done safely in
> other cases. Even if it can be done safely, then it will require
> significant analysis to get it right. And even if it gets done
> right, then there is a high risk that that a bug will be introduced
> during maintenance later, because the maintenance programmer do not
> have the skill or the time to understand the subtleties of the
> problem.
>
> #B can always be done safely. It requires not much work. And
> is relative maintenance friendly.

     The O.P.'s use case involved third-party "suspect code" that
might dive into an infinite loop somewhere unexpected.  I think
that rules out #B because you might overlook the fatal loop while
salting "should I stop now?" tests throughout the code (you might
not even have the freedom to insert tests).  I'd say the "suspect"
nature of the code also rules out #A, if #A is possible at all
(I'm not convinced it is).

     There's a #C, though: Run the suspect code in its own JVM, as
a separate process.  If it goes silent for a long time, kill the
entire process.  You don't need to worry about the integrity of a
JVM that's no longer living, and any corruption inside the dead
process' address space won't contaminate your own.

-- 
Eric Sosman
esosman@comcast-dot-net.invalid

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


#24882

FromArne Vajhøj <arne@vajhoej.dk>
Date2013-08-02 21:51 -0400
Message-ID<51fc621a$0$303$14726298@news.sunsite.dk>
In reply to#24871
On 8/1/2013 11:49 AM, Eric Sosman wrote:
> On 8/1/2013 11:25 AM, Arne Vajhøj wrote:
>> [...]
>> I think it is something like:
>>
>> You can achieve what you want to do in two ways:
>> A) use Thread.stop
>> B) set a flag and let the thread do what it need to do to
>>     terminate in a graceful manner
>>
>> #A can be done safely in some cases and can not be done safely in
>> other cases. Even if it can be done safely, then it will require
>> significant analysis to get it right. And even if it gets done
>> right, then there is a high risk that that a bug will be introduced
>> during maintenance later, because the maintenance programmer do not
>> have the skill or the time to understand the subtleties of the
>> problem.
>>
>> #B can always be done safely. It requires not much work. And
>> is relative maintenance friendly.
>
>      The O.P.'s use case involved third-party "suspect code" that
> might dive into an infinite loop somewhere unexpected.  I think
> that rules out #B because you might overlook the fatal loop while
> salting "should I stop now?" tests throughout the code (you might
> not even have the freedom to insert tests).  I'd say the "suspect"
> nature of the code also rules out #A, if #A is possible at all
> (I'm not convinced it is).
>
>      There's a #C, though: Run the suspect code in its own JVM, as
> a separate process.  If it goes silent for a long time, kill the
> entire process.  You don't need to worry about the integrity of a
> JVM that's no longer living, and any corruption inside the dead
> process' address space won't contaminate your own.

Not being able to change the code that needs to be interrupted
is a difficult case.

#C may be the only option for that case.

Arne

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


#24872

Fromtaqmcg@gmail.com
Date2013-08-01 09:30 -0700
Message-ID<bb16ff48-e2f7-4d2c-8910-24107773b77b@googlegroups.com>
In reply to#24869
On Thursday, August 1, 2013 11:25:25 AM UTC-4, Arne Vajhøj wrote:
> On 8/1/2013 11:00 AM, usvirtualobservatory@gmail.com wrote:
> 
> I think it is something like:
> 
> 
> 
> You can achieve what you want to do in two ways: 
> A) use Thread.stop
> B) set a flag and let the thread do what it need to do to
>     terminate in a graceful manner
> 
> 
> #A can be done safely in some cases and can not be done safely in
> other cases. Even if it can be done safely, then it will require
> significant analysis to get it right. And even if it gets done
> right, then there is a high risk that that a bug will be introduced
> during maintenance later, because the maintenance programmer do not
> have the skill or the time to understand the subtleties of the
> problem.
> 
> 
> 
> #B can always be done safely. It requires not much work. And
> is relative maintenance friendly.
> 
> Easy choice in my opinion.
> 
> Arne

Sure...  If you control all the code, and your code has no bugs in it (so that no infinite loop occurs somewhere you didn't expect).  That's not always the case -- I certainly expect that my code has bugs and I use a fair number of external libraries which may have bugs of there own.

Since most of my task code is single threaded and numerical, and I'd plan on throwing away anything touched by a killed thread, a lot of the concerns that are brought up seem more handleable than might be the case in other applications.

   Tom

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


#24873

Frommarkspace <markspace@nospam.nospam>
Date2013-08-01 10:01 -0700
Message-ID<kte3tf$3sa$1@dont-email.me>
In reply to#24872
On 8/1/2013 9:30 AM, taqmcg@gmail.com wrote:

> Sure...  If you control all the code, and your code has no bugs in it
> (so that no infinite loop occurs somewhere you didn't expect).
> That's not always the case -- I certainly expect that my code has
> bugs and I use a fair number of external libraries which may have
> bugs of there own.


Well, the better option is to use a library without major bugs that 
require Thread.stop().  Numerical libraries are fairly common, can you 
find one that doesn't hang?

Another better option is to use Thread.interrupt().  That's a flag 
defined for you in the system and checked often by many system 
libraries.  It's a clean way of stopping a thread.

Another better option is to decompile the library code (not hard for 
byte code, somewhat hard for machine code) and insert a check for 
Thread.interrupt() or some other flag or condition, so that you don't 
need to use Thread.stop().

But yes it's possible to use Thread.stop() in extremis.  I wouldn't 
though.  Use System.exit() instead, if things have really gone that far 
off the rails.  Better to cleanly shutdown the JVM than risk weird bugs 
or whatnot.  However, see the "find a less buggy library" option up top.

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


#24883

FromArne Vajhøj <arne@vajhoej.dk>
Date2013-08-02 21:55 -0400
Message-ID<51fc630b$0$303$14726298@news.sunsite.dk>
In reply to#24872
On 8/1/2013 12:30 PM, taqmcg@gmail.com wrote:
> On Thursday, August 1, 2013 11:25:25 AM UTC-4, Arne Vajhøj wrote:
>> On 8/1/2013 11:00 AM, usvirtualobservatory@gmail.com wrote:
>> I think it is something like:
>>
>> You can achieve what you want to do in two ways:
>> A) use Thread.stop
>> B) set a flag and let the thread do what it need to do to
>>      terminate in a graceful manner
>>
>> #A can be done safely in some cases and can not be done safely in
>> other cases. Even if it can be done safely, then it will require
>> significant analysis to get it right. And even if it gets done
>> right, then there is a high risk that that a bug will be introduced
>> during maintenance later, because the maintenance programmer do not
>> have the skill or the time to understand the subtleties of the
>> problem.
>>
>> #B can always be done safely. It requires not much work. And
>> is relative maintenance friendly.
>>
>> Easy choice in my opinion.
>
> Sure...  If you control all the code, and your code has no bugs in it
> (so that no infinite loop occurs somewhere you didn't expect).
> That's not always the case -- I certainly expect that my code has
> bugs and I use a fair number of external libraries which may have
> bugs of there own.

They assume that you control the code.

They do not assume that there are no unexpected bugs. They just
don't handle the unexpected bugs.

> Since most of my task code is single threaded and numerical, and I'd
> plan on throwing away anything touched by a killed thread, a lot of
> the concerns that are brought up seem more handleable than might be
> the case in other applications.

And you may get it to work.

But why spend more time on a worse solution?

Arne

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


Page 1 of 3  [1] 2 3  Next page →

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


csiph-web