解析 Thread 中三种跟线程中断有关的方法

时间:2018年10月3日


1. interrupt()

interrupt() 这个方法是将当前线程的中断状态为 true,即调用 isInterrupted() 将返回 true。

其具体实现如下:

public void interrupt() {

    // 只有自己才能够中断自己
    // checkAccess() 这方法会抛出 SecurityException
    if (this != Thread.currentThread())
        checkAccess();

    synchronized (blockerLock) {
        Interruptible b = blocker;
        if (b != null) {
            interrupt0(); // Just to set the interrupt flag
            b.interrupt(this);
            return;
        }
    }
    interrupt0();
}

下面来看看例子:

public class InterruptedTheadTest {

	public static void main(String[] args) {
		Thread.currentThread().interrupt();
        System.out.println("the current thread has been interrupted!");
	}
}

结果输出:

the current thread has been interrupted!

结果与单独打印上面这句话一样。为什么不会抛出中断异常呢?

那这个方法到底该怎么用呢?实际上,这个方法是针对于阻塞的线程的。什么意思呢?就是当 处于阻塞的线程 调用 interrupt() 方法,将会抛出 InterruptException 异常。

下面让我们来稍微修改一下上面的代码:

public class InterruptedTheadTest {

	public static void main(String[] args) {
		Thread.currentThread().interrupt();
		try {
			Thread.currentThread().sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
			System.out.println("the current thread has been interrupted!");
		}
	}
}

结果输出:

java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.wfms.concurrency.TestInterruptedThead.main(TestInterruptedThead.java:8)
the current thread has been interrupted!

2. isInterrupted()

直接来看源码:

public boolean isInterrupted() {
    return isInterrupted(false);
}


 /**
  * @param CleanInterrupted,true 返回当前线程的中断状态,并清除其中断状态
  * @param CleanInterrupted,false 返回当前线程的中断状态,不清除其中断状态
  */
private native boolean isInterrupted(boolean ClearInterrupted);

isInterrupted() 内部调用了 isInterrupted(false) ,这个方法是测试当前线程的中断状态。

3. interrupted()

public static boolean interrupted() {
    return currentThread().isInterrupted(true);
}

前面我们已经介绍过 isInterrupted(boolean) 这个方法,可知 interrupted() 这个方法返回当前线程的中断状态之后,再将其中断状态清除掉。

下面来演示对比 isInterrupted() 和 interrupted() 这两个方法的区别:

public class InterruptedTheadTest {

	public static void main(String[] args) {
		compareIsInterruptedAndInterrupted();
	}
	
	public static void compareIsInterruptedAndInterrupted() {
		Thread t1 = new Thread(new Runnable() {

			@Override
			public void run() {
				Thread.currentThread().interrupt();
				boolean isInterrupted = Thread.currentThread().isInterrupted();
				System.out.println("t1: before call isInterruped: " + isInterrupted);
				isInterrupted = Thread.currentThread().isInterrupted();
				System.out.println("t1: after call isInterrupted: " + isInterrupted);
			}
			
		});
		
		Thread t2 = new Thread(new Runnable() {

			@Override
			public void run() {
				Thread.currentThread().interrupt();
				boolean isInterrupted = Thread.currentThread().interrupted();
				System.out.println("t2: before call interrupted: " + isInterrupted);
				isInterrupted = Thread.currentThread().interrupted();
				System.out.println("t2: after call interrupted: " + isInterrupted);
			}
			
		});
		
		t1.start();
		t2.start();
		
	}
}

结果输出:

t1: before call isInterruped: true
t2: before call interrupted: true
t1: after call isInterrupted: true
t2: after call interrupted: false

4. 总结

BACK