stop() boundaries

Discussion in 'Java' started by Jan Burse, Dec 25, 2010.

  1. Jan Burse

    Jan Burse Guest

    Dear All

    Suppose I have the following code:

    A; /* line 1 */
    try { /* line 2 */
    B; /* line 3 */
    } finally {
    C;
    }

    Now I run this in a thread and arbitrarily
    call the deprecated (sic!) stop() once.

    Would it be possible that the stop will
    throw a thread death error on line 2,
    thus after A has been executed and before
    the try block is entered?

    Bye
    Jan Burse, Dec 25, 2010
    #1
    1. Advertising

  2. Jan Burse

    Jan Burse Guest

    Patricia Shanahan schrieb:
    > Jan Burse wrote:
    >> Dear All
    >>
    >> Suppose I have the following code:
    >>
    >> A; /* line 1 */
    >> try { /* line 2 */
    >> B; /* line 3 */
    >> } finally {
    >> C;
    >> }
    >>

    >
    > You have to assume that the exception can be thrown anywhere, because it
    > is documented to be thrown "almost anywhere", and, as far as I know,
    > there is no documentation guaranteeing that it won't happen in any
    > particular place. In your case, I see nothing special about statement A
    > that would prevent a ThreadDeath before, during, or immediately after A.
    >


    Usually try/catch/finally blocks disappear somehow in the
    compiled code, and are replaced by a lookup table. So I guess
    it is not possible to abort the thread at line 2. Either we
    are inside the try block and in front of B, or outside of the
    try block and in front of A, or inside A. Or somewhere else.

    But I am not sure about this hypothesis. It would be a clarification
    of the "almost anywhere", and would be an interesting invariant of
    stop().

    Bye
    Jan Burse, Dec 25, 2010
    #2
    1. Advertising

  3. In article <if5e2e$sh6$>,
    Jan Burse <> wrote:

    > Dear All
    >
    > Suppose I have the following code:
    >
    > A; /* line 1 */
    > try { /* line 2 */
    > B; /* line 3 */
    > } finally {
    > C;
    > }
    >
    > Now I run this in a thread and arbitrarily
    > call the deprecated (sic!) stop() once.
    >
    > Would it be possible that the stop will
    > throw a thread death error on line 2,
    > thus after A has been executed and before
    > the try block is entered?
    >
    > Bye


    Line 2 produces an exception table, not code. Line 3 may be wrapped
    with some code for the finally block. Execution of 'C' may be aborted
    by stop(), and that's why stop() is no longer supported.

    You can use Thread interrupts to abort non-blocking code by polling
    Thread.interrupted() or Thread.isInterrupted() and manually throwing
    InterruptedException. You can also poll a volatile boolean field.
    --
    I will not see posts or email from Google because I must filter them as spam
    Kevin McMurtrie, Dec 25, 2010
    #3
  4. Jan Burse

    Lew Guest

    On 12/25/2010 01:44 PM, Jan Burse wrote:
    > Dear All
    >
    > Suppose I have the following code:
    >
    > A; /* line 1 */
    > try { /* line 2 */
    > B; /* line 3 */
    > } finally {
    > C;
    > }
    >
    > Now I run this in a thread and arbitrarily
    > call the deprecated (sic!) stop() once.


    Yes, they do call it "deprecated", and it is that in both the English and the
    Java sense.

    http://download.oracle.com/javase/6/docs/api/java/lang/Thread.html#stop()
    > *Deprecated.*
    > 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.


    "This method is inherently unsafe."

    > For more information, see Why are Thread.stop, Thread.suspend
    > and Thread.resume Deprecated?.


    http://download.oracle.com/javase/6...s/concurrency/threadPrimitiveDeprecation.html
    > Why is Thread.stop deprecated?
    > Because it is inherently unsafe.

    ....
    > Unlike other unchecked exceptions, ThreadDeath kills threads silently;
    > thus, the user has no warning that his program may be corrupted.


    "... it is inherently unsafe."

    "Inherently" is a pretty strong word.

    What are you trying to accomplish?

    --
    Lew
    Ceci n'est pas une pipe.
    Lew, Dec 26, 2010
    #4
  5. Jan Burse

    Jan Burse Guest

    Lew schrieb:
    > "... it is inherently unsafe."
    >
    > "Inherently" is a pretty strong word.
    >
    > What are you trying to accomplish?


    Proper use of java.util.concurrent in the same sense
    as synchronized works.

    They also say in the documentation that ThreadDeath will
    unravel synchronized statements. So under the hood they
    must have some boundaries and some finally blocks.

    So when I use the native monitors, I will have what
    stop() boundaries here?

    A;
    synchronized (obj) {
    B;
    }
    C;


    Assume I am now using something like:

    A;
    ReentrantLock lock=new ReentrantLock();
    lock.lock();
    try {
    B;
    } finally {
    lock.unlock()
    }
    C;

    Will it *always* unravel my lock when using stop()?
    Under the assumption that B does not throw any exception
    except when it gets a ThreadDeath injected.

    Is it possible that a ThreadDeath is injected after
    lock.lock() and before try, so that lock.unlock() is
    not called?

    Bye
    Jan Burse, Dec 26, 2010
    #5
  6. Jan Burse

    Jan Burse Guest

    Jan Burse schrieb:
    > ReentrantLock lock=new ReentrantLock();


    Oops creation is done somewhere else, at a share place,
    remove this line from the question.
    Jan Burse, Dec 26, 2010
    #6
  7. Jan Burse

    Lew Guest

    Lew schrieb:
    >>> "... it is inherently unsafe."
    >>>
    >>> "Inherently" is a pretty strong word.
    >>>
    >>> What are you trying to accomplish?


    Jan Burse wrote:
    >> Proper use of java.util.concurrent in the same sense
    >> as synchronized works.


    That's part of what I'm looking for. Now for the rest of my curiosity, WHY
    are you investigating 'stop()' in particular? You do know that you aren't
    supposed to use it at all, ever, right? So why 'stop()'?

    What exactly does "proper use of java.util.concurrent" have to do with
    'stop()'? I see no connection whatsoever, other than that the former obviates
    the latter.

    Patricia Shanahan wrote:
    > Remember that stop is deprecated because it is inherently unsafe. I
    > don't think you are going to be able to base anything "proper" on such a
    > shaky foundation.
    >
    > The flag-and-interrupt approach provides a much more solid foundation.


    Jan Burse wrote:
    >> A;
    >> ReentrantLock lock=new ReentrantLock();
    >> lock.lock();
    >> try {
    >> B;
    >> } finally {
    >> lock.unlock()
    >> }
    >> C;
    >>
    >> Will it *always* unravel my lock when using stop()?
    >> Under the assumption that B does not throw any exception
    >> except when it gets a ThreadDeath injected.
    >>
    >> Is it possible that a ThreadDeath is injected after
    >> lock.lock() and before try, so that lock.unlock() is
    >> not called?


    Patricia Shanahan wrote:
    > You seem to be thinking of lock.lock() as an atomic unit that cannot be
    > partly executed before a stop. Is that right? If so, do you have any
    > basis for that assumption? I don't see anything in the relevant code
    > that would prevent a stop and ThreadDeath.
    >
    > If that assumption is not justified, you need to consider cases such as
    > the stop hitting with the return from lock.lock() as the next statement.
    > The lock is locked, but control has not returned to your code, and
    > execution is still outside your try-finally block. Even worse, the stop
    > may hit in the middle of ReentrantLock.Sync.nonfairTryAcquire(), leaving
    > the lock in an inconsistent state.
    >
    > I believe this sort of issue lead to the recognition that stop() could
    > not be used safely, and the decision get rid of the problem by
    > deprecating it.


    In other words, "DO NOT EVER USE 'Thread#stop()'!"

    --
    Lew
    Ceci n'est pas une pipe.
    Lew, Dec 26, 2010
    #7
  8. In article <if7el3$uph$>,
    Jan Burse <> wrote:

    > Lew schrieb:
    > > "... it is inherently unsafe."
    > >
    > > "Inherently" is a pretty strong word.
    > >
    > > What are you trying to accomplish?

    >
    > Proper use of java.util.concurrent in the same sense
    > as synchronized works.
    >
    > They also say in the documentation that ThreadDeath will
    > unravel synchronized statements. So under the hood they
    > must have some boundaries and some finally blocks.
    >
    > So when I use the native monitors, I will have what
    > stop() boundaries here?
    >
    > A;
    > synchronized (obj) {
    > B;
    > }
    > C;
    >
    >
    > Assume I am now using something like:
    >
    > A;
    > ReentrantLock lock=new ReentrantLock();
    > lock.lock();
    > try {
    > B;
    > } finally {
    > lock.unlock()
    > }
    > C;
    >
    > Will it *always* unravel my lock when using stop()?


    No. lock.unlock() can be called normally then aborted by a call to
    stop().

    More importantly, protecting B with a lock implies that it is modifying
    shared data in a non-atomic manner. That implies that aborting it in an
    undeclared location would leave damaged shared data behind.
    --
    I will not see posts or email from Google because I must filter them as spam
    Kevin McMurtrie, Dec 26, 2010
    #8
  9. "Jan Burse" <> wrote in message
    news:if7el3$uph$...
    > Lew schrieb:
    >> "... it is inherently unsafe."
    >>
    >> "Inherently" is a pretty strong word.
    >>
    >> What are you trying to accomplish?

    >
    > Proper use of java.util.concurrent in the same sense
    > as synchronized works.


    If the question is "How do I protect use of concurrent classes against
    clients calling stop()?", I'm fairly sure the answer is "You can't".
    Mike Schilling, Dec 27, 2010
    #9
  10. Jan Burse

    Daniel Pitts Guest

    On 12/26/2010 5:06 AM, Jan Burse wrote:
    > Lew schrieb:
    >> "... it is inherently unsafe."
    >>
    >> "Inherently" is a pretty strong word.
    >>
    >> What are you trying to accomplish?

    >
    > Proper use of java.util.concurrent in the same sense
    > as synchronized works.
    >
    > They also say in the documentation that ThreadDeath will
    > unravel synchronized statements. So under the hood they
    > must have some boundaries and some finally blocks.
    >
    > So when I use the native monitors, I will have what
    > stop() boundaries here?
    >
    > A;
    > synchronized (obj) {
    > B;
    > }
    > C;
    >
    >
    > Assume I am now using something like:
    >
    > A;
    > ReentrantLock lock=new ReentrantLock();
    > lock.lock();
    > try {
    > B;
    > } finally {
    > lock.unlock()
    > }
    > C;
    >
    > Will it *always* unravel my lock when using stop()?
    > Under the assumption that B does not throw any exception
    > except when it gets a ThreadDeath injected.

    It is possible that stop() causes the exception to be thrown just before
    "lock.unlock" is executed, but after B has executed. So, your "finally"
    may be bypassed. Oops.

    Even worse, it could be that your lock is *half* unlocked, because it
    isn't expecting to be interrupted in the middle of its operation, but
    Thread.stop() does just that.

    So, just don't do it. There are good reasons its been deprecated.

    >
    > Is it possible that a ThreadDeath is injected after
    > lock.lock() and before try, so that lock.unlock() is
    > not called?
    >
    > Bye
    >
    >
    >
    >



    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
    Daniel Pitts, Jan 8, 2011
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Laura
    Replies:
    1
    Views:
    398
    Laura
    Jun 3, 2004
  2. Replies:
    4
    Views:
    470
  3. Ken
    Replies:
    1
    Views:
    341
    Thomas Fritsch
    Sep 15, 2004
  4. Boundaries

    , May 1, 2005, in forum: Java
    Replies:
    0
    Views:
    430
  5. PilotYid
    Replies:
    3
    Views:
    799
    Douwe
    Feb 10, 2006
Loading...

Share This Page