| <!doctype html> | |
| <!-- | |
| Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. | |
| DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| This code is free software; you can redistribute it and/or modify it | |
| under the terms of the GNU General Public License version 2 only, as | |
| published by the Free Software Foundation. Oracle designates this | |
| particular file as subject to the "Classpath" exception as provided | |
| by Oracle in the LICENSE file that accompanied this code. | |
| This code is distributed in the hope that it will be useful, but WITHOUT | |
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| version 2 for more details (a copy is included in the LICENSE file that | |
| accompanied this code). | |
| You should have received a copy of the GNU General Public License version | |
| 2 along with this work; if not, write to the Free Software Foundation, | |
| Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| or visit www.oracle.com if you need additional information or have any | |
| questions. | |
| --> | |
| <html lang="en"> | |
| <head> | |
| <title>Java Thread Primitive Deprecation</title> | |
| </head> | |
| <body> | |
| <h1>Java Thread Primitive Deprecation</h1> | |
| <hr> | |
| <h2>Why is <code>Thread.stop</code> deprecated and the ability to | |
| stop a thread removed?</h2> | |
| <p>Because it was inherently unsafe. Stopping a thread caused it to | |
| unlock all the monitors that it had locked. (The monitors were | |
| unlocked as the <code>ThreadDeath</code> exception propagated up | |
| the stack.) If any of the objects previously protected by these | |
| monitors were in an inconsistent state, other threads may have viewed | |
| these objects in an inconsistent state. Such objects are said to be | |
| <i>damaged</i>. 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, | |
| <code>ThreadDeath</code> killed threads silently; thus, the user had | |
| no warning that their program may be corrupted. The corruption could | |
| manifest itself at any time after the actual damage occurs, even | |
| hours or days in the future.</p> | |
| <hr> | |
| <h2>Couldn't I have just caught <code>ThreadDeath</code> and fixed | |
| the damaged object?</h2> | |
| <p>In theory, perhaps, but it would <em>vastly</em> complicate the | |
| task of writing correct multithreaded code. The task would be | |
| nearly insurmountable for two reasons:</p> | |
| <ol> | |
| <li>A thread could throw a <code>ThreadDeath</code> exception | |
| <i>almost anywhere</i>. All synchronized methods and blocks would | |
| have to be studied in great detail, with this in mind.</li> | |
| <li>A thread could throw a second <code>ThreadDeath</code> exception | |
| while cleaning up from the first (in the <code>catch</code> or | |
| <code>finally</code> clause). Cleanup would have to be repeated till | |
| it succeeded. The code to ensure this would be quite complex.</li> | |
| </ol> | |
| In sum, it just isn't practical. | |
| <hr> | |
| <h2>What should I use instead of <code>Thread.stop</code>?</h2> | |
| <p>Most uses of <code>stop</code> should be replaced by code that | |
| simply modifies some variable to indicate that the target thread | |
| should stop running. The target thread should check this variable | |
| regularly, and return from its run method in an orderly fashion if | |
| the variable indicates that it is to stop running. To ensure prompt | |
| communication of the stop-request, the variable must be | |
| <code>volatile</code> (or access to the variable must be | |
| synchronized).</p> | |
| <p>For example, suppose your application contains the following | |
| <code>start</code>, <code>stop</code> and <code>run</code> | |
| methods:</p> | |
| <pre> | |
| private Thread blinker; | |
| public void start() { | |
| blinker = new Thread(this); | |
| blinker.start(); | |
| } | |
| public void stop() { | |
| blinker.stop(); // UNSAFE! | |
| } | |
| public void run() { | |
| while (true) { | |
| try { | |
| Thread.sleep(interval); | |
| } catch (InterruptedException e){ | |
| } | |
| blink(); | |
| } | |
| } | |
| </pre> | |
| You can avoid the use of <code>Thread.stop</code> by replacing the | |
| application's <code>stop</code> and <code>run</code> methods with: | |
| <pre> | |
| private volatile Thread blinker; | |
| public void stop() { | |
| blinker = null; | |
| } | |
| public void run() { | |
| Thread thisThread = Thread.currentThread(); | |
| while (blinker == thisThread) { | |
| try { | |
| Thread.sleep(interval); | |
| } catch (InterruptedException e){ | |
| } | |
| blink(); | |
| } | |
| } | |
| </pre> | |
| <hr> | |
| <h2>How do I stop a thread that waits for long periods (e.g., for | |
| input)?</h2> | |
| <p>That's what the <code>Thread.interrupt</code> method is for. The | |
| same "state based" signaling mechanism shown above can be used, but | |
| the state change (<code>blinker = null</code>, in the previous | |
| example) can be followed by a call to | |
| <code>Thread.interrupt</code>, to interrupt the wait:</p> | |
| <pre> | |
| public void stop() { | |
| Thread moribund = waiter; | |
| waiter = null; | |
| moribund.interrupt(); | |
| } | |
| </pre> | |
| For this technique to work, it's critical that any method that | |
| catches an interrupt exception and is not prepared to deal with it | |
| immediately reasserts the exception. We say <em>reasserts</em> | |
| rather than <em>rethrows</em>, because it is not always possible to | |
| rethrow the exception. If the method that catches the | |
| <code>InterruptedException</code> is not declared to throw this | |
| (checked) exception, then it should "reinterrupt itself" with the | |
| following incantation: | |
| <pre> | |
| Thread.currentThread().interrupt(); | |
| </pre> | |
| This ensures that the Thread will reraise the | |
| <code>InterruptedException</code> as soon as it is able. | |
| <hr> | |
| <h2>What if a thread doesn't respond to | |
| <code>Thread.interrupt</code>?</h2> | |
| <p>In some cases, you can use application specific tricks. For | |
| example, if a thread is waiting on a known socket, you can close | |
| the socket to cause the thread to return immediately. | |
| Unfortunately, there really isn't any technique that works in | |
| general. <em>It should be noted that in all situations where a | |
| waiting thread doesn't respond to <code>Thread.interrupt</code>, it | |
| wouldn't respond to <code>Thread.stop</code> either.</em> Such | |
| cases include deliberate denial-of-service attacks, and I/O | |
| operations for which thread.stop and thread.interrupt do not work | |
| properly.</p> | |
| </body> | |
| </html> |