interrupt()
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // 仅仅设置interrupt标志位
b.interrupt(this); // 调用如 I/O 操作定义的中断方法
return;
}
}
interrupt0();
}
// 仅仅设置interrupt标志位
private native void interrupt0();
-
interrupt 中断操作时,非自身中断需要先检测是否有中断权限,这由jvm的安全机制配置;
-
同步阻塞判断blocker是不是null,如果不是 先设置中断标志,然后调用如 I/O 操作定义的中断方法 然后返回,什么情况下 blocker不是null呢,或者说什么时候会退出被阻塞状态呢
如果线程处于sleep, wait,join等状态, 那么线程将立即退出被阻塞状态, 并抛出一个InterruptedException异常
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
public static native void sleep(long millis) throws InterruptedException;
sleep是THread的方法,是个native方法
* @exception InterruptedException if any thread interrupted the
* current thread before or while the current thread
* was waiting for a notification. The <i>interrupted
* status</i> of the current thread is cleared when
* this exception is thrown.
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
*/
public final native void wait(long timeout) throws InterruptedException;
wait是Object的方法,也是个native方法
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
join方法也是Thread类的方法,看它实现他最终是会调用Obj.wait方法
综上所述和native的注释,当线程处于sleep, wait,join时,如果线程中断,线程会抛出InterruptedException并清除中断状态
* <p> If a thread's interrupt status is already set and it invokes a blocking
* I/O operation upon a channel then the channel will be closed and the thread
* will immediately receive a {@link ClosedByInterruptException}; its interrupt
* status will remain set.
*
* <p> A channel supports asynchronous closing and interruption if, and only
* if, it implements this interface. This can be tested at runtime, if
* necessary, via the <tt>instanceof</tt> operator.
*
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public interface InterruptibleChannel
extends Channel
{
/**
* Closes this channel.
*
* <p> Any thread currently blocked in an I/O operation upon this channel
* will receive an {@link AsynchronousCloseException}.
*
* <p> This method otherwise behaves exactly as specified by the {@link
* Channel#close Channel} interface. </p>
*
* @throws IOException If an I/O error occurs
*/
public void close() throws IOException;
}
- java nio里的channel是实现自InterruptibleChannel接口的,这个接口的注释里有说明,当正在操作这个channel的线程被其他线程中断,则会close这个channel,当前(被中断的)线程抛出一个ClosedByInterruptException异常。具体的可以看sun.nio.ch.SocketChannelImpl.write 方法内部实现有判断中断标志
* <p> This method performs a blocking <a href="#selop">selection
* operation</a>. It returns only after at least one channel is selected,
* this selector's {@link #wakeup wakeup} method is invoked, or the current
* thread is interrupted, whichever comes first. </p>
*
* @return The number of keys, possibly zero,
* whose ready-operation sets were updated
*
* @throws IOException
* If an I/O error occurs
*
* @throws ClosedSelectorException
* If this selector is closed
*/
public abstract int select() throws IOException;
- 如果线程在Selector上被阻塞,如果interrupted,select方法将立即返回不会抛出异常
- 如果非以上情况,将直接标记 interrupt 状态
小结:interrupt()只有再2、3、4的情况下,线程中断标志后,线程才会抛出异常或者退出,并且清除中断状态,其他情况只会标记中断状态为true,不会中断线程,程序可以自己根据中断标志做出对应的处理
interrupted()、isInterrupted()
//静态方法,调用该方法调用后会清除中断状态
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
// 这个方法不会清除中断状态
public boolean isInterrupted() {
return isInterrupted(false);
}
//返回中断状态标志,参数代表是否清除中断状态
private native boolean isInterrupted(boolean ClearInterrupted);
- interrupted()
这是个静态方法,返回中断状态标志,并清除中断状态
- isInterrupted
返回中断状态标志,不清除中断状态
代码示例
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
StopThread thread = new StopThread();
thread.start();
Thread.sleep(1000);
thread.interrupt();
}
private static class StopThread extends Thread {
@Override
public void run() {
try {
// 休眠3秒,模拟耗时操作
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前线程状态:" + Thread.currentThread().isInterrupted());
}
}
}
1.线程进入sleep状态
2.线程中断标志
3.线程抛出异常并清除中断状态
4.打印中断状态为false
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
StopThread thread = new StopThread();
thread.start();
}
private static class StopThread extends Thread {
@Override
public void run() {
Thread.currentThread().interrupt();
System.out.println("1当前线程状态:" + Thread.currentThread().isInterrupted());
System.out.println("2当前线程状态:" + Thread.interrupted());
System.out.println("3当前线程状态:" + Thread.currentThread().isInterrupted());
}
}
}
1.线程中断标志
2.返回线程中断状态为true,不清除中断状态
3.返回线程中断状态为true,并清除中断状态
4.返回线程中断状态为false