浅析Java线程的正确停止

线程错误终止之destroy与stop方法

记得以前初学Java的时候,由于缺少对锁、同步、异步等这些线程的知识,想当然的以为destroy与stop方法都能正确的停止Java线程的执行。但是,后来随着工作的积累,以及对线程安全的一些理解,慢慢认识到这两个方法是有问题的,并且这两方法也早已在java doc上被指名是弃用的。

destroy()这个方法其实根本没干什么事情,只是抛出了一个NoSuchMethodError,所以说该方法无法终止线程,因此不能望文生意:

/*** Throws {@link NoSuchMethodError}.** @deprecated This method was originally designed to destroy this*thread without any cleanup. Any monitors it held would have*remained locked. However, the method was never implemented.*If if were to be implemented, it would be deadlock-prone in*much the manner of {@link #suspend}. If the target thread held*a lock protecting a critical system resource when it was*destroyed, no thread could ever access this resource again.*If another thread ever attempted to lock this resource, deadlock*would result. Such deadlocks typically manifest themselves as*"frozen" processes. For more information, see*<a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">*Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.* @throws NoSuchMethodError always*/@Deprecatedpublic void destroy() {throw new NoSuchMethodError();}对于stop方法,其本质就是因为会线程不安全,它会直接终止run方法的调用,并且会抛出一个ThreadDeath错误,如果线程持有某个对象锁的话,会完全释放锁,导致对象状态不一致。具体细节可以看官方的java doc;Deprecated. This method was originally designed to destroy this thread without any cleanup. Any monitors it held would have remained locked. However, the method was never implemented. If if were to be implemented, it would be deadlock-prone in much the manner of suspend(). If the target thread held a lock protecting a critical system resource when it was destroyed, no thread could ever access this resource again. If another thread ever attempted to lock this resource, deadlock would result. Such deadlocks typically manifest themselves as "frozen" processes. For more information, see Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.线程的正确终止

在上述的destroy和stop方法都一一被否定之后,那还有什么方式能够正确多终止线程呢?总的来说,在java中有两种解决方案:

标志,在run方法中通过一个标记来进行结束,由于该方式很寻常就不做举例interrupt,通过异常中断

下面就主要针对interrupt进行展开探讨。

/*** Interrupts this thread.** <p> Unless the current thread is interrupting itself, which is* always permitted, the {@link #checkAccess() checkAccess} method* of this thread is invoked, which may cause a {@link* SecurityException} to be thrown.** <p> If this thread is blocked in an invocation of the {@link* Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link* Object#wait(long, int) wait(long, int)} methods of the {@link Object}* class, or of the {@link #join()}, {@link #join(long)}, {@link* #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},* methods of this class, then its interrupt status will be cleared and it* will receive an {@link InterruptedException}.** <p> If this thread is blocked in an I/O operation upon an {@link* java.nio.channels.InterruptibleChannel </code>interruptible* channel<code>} then the channel will be closed, the thread's interrupt* status will be set, and the thread will receive a {@link* java.nio.channels.ClosedByInterruptException}.** <p> If this thread is blocked in a {@link java.nio.channels.Selector}* then the thread's interrupt status will be set and it will return* immediately from the selection operation, possibly with a non-zero* value, just as if the selector's {@link* java.nio.channels.Selector#wakeup wakeup} method were invoked.** <p> If none of the previous conditions hold then this thread's interrupt* status will be set. </p>** <p> Interrupting a thread that is not alive need not have any effect.** @throws SecurityException*if the current thread cannot modify this thread** @revised 6.0* @spec JSR-51*/public void interrupt() {if (this != Thread.currentThread())checkAccess();synchronized (blockerLock) {Interruptible b = blocker;if (b != null) {interrupt0();// Just to set the interrupt flagb.interrupt(this);return;}}interrupt0();}根据java源码摘出的interrupt方法注释和方法体的实现,,可以归纳为:通过调用interrupt方法可以使得处于阻塞状态的线程抛出一个异常,即interrupt方法可以用来中断一个正处于阻塞状态的线程;另外,改方法还会设置线程的中断状态(注:isInterrupted()可以用来查询中断状态)。实践检验真理interrupt能否中断处于非阻塞状态的线程

代码:

public class ThreadTest {/** * @param args */public static void main(String[] args) {WorkThread wThread = new WorkThread();wThread.start();System.out.println("开始调用wThread.interrupt()");wThread.interrupt();System.out.println("结束调用wThread.interrupt()");}}class WorkThread extends Thread {public void run() {for (int i = 0; i < Byte.MAX_VALUE;) {System.out.println("工作线程运行" + (++i));}}}运行结果:总在盼望未来,愿你的人生美开

浅析Java线程的正确停止

相关文章:

你感兴趣的文章:

标签云: