详解Thread类 interrupt()、interrupted()、isInterrupted() 方法
interrupt() 方法
interrupt()
方法的作用是中断线程(线程不一定是当前线程,而是指调用该方法的Thread
实例所代表的线程),但实际上只是给线程设置一个中断标志,线程仍会继续运行;
JavaSE
官方文档中对interrupt()
方法的解释如下;
interrupt()
方法源码如下;
public void interrupt() {
// 若线程中操作的不是当前线程本身,需要进行安全权限校验
if (this != Thread.currentThread())
// 权限不通过会抛出AccessControlException异常
checkAccess();
// 给线程设置中断标识
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
interrupt0();
}
下面是interrupt()
方法的简单使用;
// 此处用的是当前线程对象,interrupt()中断(中断标识)的是调用者thread线程
Thread thread = Thread.currentThread();
// 方法返回值void
thread.interrupt();
interrupted() 方法
interrupted()
方法的作用是判断当前线程是否被中断(检查中断标志),返回一个boolean
值并清除中断状态,第二次再调用时中断状态已经被清除,将返回false
;
注意,interrupted()
方法是静态方法,应当由Thread
类直接调用,判断以及清除的是当前线程中断标识,与调用者无关;
JavaSE
官方文档中对interrupted()
方法的解释如下;
interrupted()
方法源码如下;
public static boolean interrupted() {
// 清除标识ClearInterrupted默认传了true
return currentThread().isInterrupted(true);
}
// native方法
private native boolean isInterrupted(boolean ClearInterrupted);
下面是interrupted()
方法的简单使用;
boolean interrupted = Thread.interrupted();
isInterrupted() 方法
isInterrupted()
方法的作用是只判断线程是否被中断 ,不清除中断状态;且与interrupted()
方法相比,isInterrupted()
判断的是调用者线程的中断标识,并不仅仅是当前线程;
JavaSE
官方文档中对isInterrupted()
方法的解释如下;
isInterrupted()
方法源码如下;
// 清除标识ClearInterrupted为false,则只判断中断标识并未清除
public boolean isInterrupted() {
return isInterrupted(false);
}
// native方法
private native boolean isInterrupted(boolean ClearInterrupted);
下面是isInterrupted()
方法的简单使用;
Thread thread = Thread.currentThread();
boolean isInterrupted = thread.isInterrupted();
使用示例
分别测试主线程和自定义线程;
public static void main(String[] args) {
Thread main = Thread.currentThread();
// 主线程中断
main.interrupt();
boolean mainInterrupted = main.isInterrupted();
System.out.println("主线程是否中断 " + mainInterrupted);
new Thread(() -> {
Thread thread = Thread.currentThread();
System.out.println("线程开始!thread name : " + thread.getName());
// 自定义线程中断
thread.interrupt();
for (int i = 1; i < 6; i++) {
// 小于4时,执行isInterrupted,只判断不清除;大于4时,执行interrupted,判断并清除
boolean interrupted = i < 4 ? thread.isInterrupted() : Thread.interrupted();
System.out.println("执行到 i = "+ i +", 线程[ "+ thread.getName() +"] 是否中断 " + interrupted);
}
}, "自定义线程").start();
// 分别对主线程调用isInterrupted和interrupted
mainInterrupted = main.isInterrupted();
System.out.println("主线程是否中断 " + mainInterrupted);
mainInterrupted = Thread.interrupted();
System.out.println("主线程是否中断 " + mainInterrupted);
mainInterrupted = Thread.interrupted();
System.out.println("主线程是否中断 " + mainInterrupted);
mainInterrupted = main.isInterrupted();
System.out.println("主线程是否中断 " + mainInterrupted);
}
根据下面的结果可以看出;
interrupt()
方法并未对线程执行进行了实质性的中断,只是添加了中断标志;isInterrupted()
判断的是调用者线程的中断标志,若中断返回true
,否则false
,且未对中断标志进行清除;interrupted()
是由Thread
调用的静态方法,判断的是当前线程是否被中断,若被中断,则返回true
,并且会清除线程的中断标识,再次调用时,就会返回false
;
执行结果如下所示;
到此,Thread中的三个interrupt中断相关的方法已经介绍完毕;
那么,今天的你,学会了吗?