深刻了解线程中断形式
为什么废除 Thread 的 stop 函数?
1.stop 是通过立刻抛出 ThreadDeath 异样,来达到进行线程的目标,此异样抛出有可能产生在任何一时间点,包含在 catch、finally 等语句块中,然而此异样并不会引起程序退出 (笔者只测试了 Java8)。
2. 因为有异样抛出,导致线程会开释全副所持有的锁,极可能引起线程平安问题。
因为以上 2 点,stop 这种形式进行线程是不平安的。
上面是 stop 的源码 (Java8):
@Deprecated
public final void stop() {SecurityManager security = System.getSecurityManager();
if (security != null) {checkAccess();
if (this != Thread.currentThread()) {security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
}
}
// A zero status value corresponds to "NEW", it can't change to
// not-NEW because we hold the lock.
if (threadStatus != 0) {resume(); // Wake up thread if it was suspended; no-op otherwise
}
// The VM can handle all thread states
stop0(new ThreadDeath());
}
private native void stop0(Object o);
上述源码中要害代码就是 stop0(new ThreadDeath()) 函数,这是 Native 函数,传递的参数是 ThreadDeath,ThreadDeath 是一个异样对象,该对象从 Native 层抛到了 Java 层,从而导致线程进行,不过此异样并不会引起程序退出。
很多时候为了保障数据安全,线程中会编写同步代码,如果当线程正在执行同步代码时,此时调用 stop,引起抛出异样,导致线程持有的锁会全副开释,此时就不能确保数据的安全性,呈现无奈预期的错乱数据,还有可能导致存在须要被开释的资源得不到开释,引发内存泄露。所以用 stop 进行线程是不举荐的。
用 Thread 的 interrupt 完结线程
其实调用 Thread 对象的 interrupt 函数并不是立刻中断线程,只是将线程中断状态标记设置为 true,当线程运行中有调用其阻塞的函数(Thread.sleep,Object.wait,Thread.join 等)时,阻塞函数调用之后,会一直地轮询检测中断状态标记是否为 true,如果为 true,则进行阻塞并抛出 InterruptedException 异样,同时还会重置中断状态标记;如果为 false,则持续阻塞,直到阻塞失常完结。
对于 Thread 的动态函数 interrupted 与 Thread 的对象函数 isInterrupted
这两个函数的源码:
public static boolean interrupted() {return currentThread().isInterrupted(true);
}
public boolean isInterrupted() {return isInterrupted(false);
}
/**
* Tests if some Thread has been interrupted. The interrupted state
* is reset or not based on the value of ClearInterrupted that is
* passed.
*/
private native boolean isInterrupted(boolean ClearInterrupted);
从源码中能够看出,2 函数都是调用了 Native 函数 private native boolean isInterrupted(boolean ClearInterrupted);
,前者调用传的参数为 true,所以,调用 interrupted 函数,会在检测线程中断状态标记是否为 true 后,还会将中断状态标记重置为 false。而 isInterrupted 函数只是检测线程中断状态标记
Java 线程中断的正确姿态
线程中如何解决 InterruptedException