深刻了解线程中断形式
为什么废除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