1.背景
Thread类中有三个与interrupt有关的方法,他们看起来很像,也很容易混淆,这里做一个小的总结。
2.Java线程中interrupt方法
2.1 interrupt
interrupt是Thread类的实例方法,它的主要作用是给目标线程发送一个通知,有人希望你退出啦,同时会将目标线程的中断标志设置为true,也就是已经有人打断过该线程了。至于目标线程如何处理,完全取决于目标线程自身。interrupt方法中断线程可以分为两种情况,第一种是打断正在运行的线程。如下所示,主线程休眠100ms后,中断t1线程,并将t1线程的中断标志设置为true。t1一直在进行while循环,当他发现自己的打断标志为true时,就自动退出。
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
while (true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println(Thread.currentThread().getName() + " has been interrupted.");
break;
}
}
});
t1.start();
TimeUnit.MILLISECONDS.sleep(100);
t1.interrupt();
}
当然,t1也可以选择在打断标志为true的情况下不退出,此时t1就一直在进行while循环。
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
while (true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println(Thread.currentThread().getName() + " has been interrupted.");
}
}
});
t1.start();
TimeUnit.MILLISECONDS.sleep(100);
t1.interrupt();
}
第二种情况是,打断正在休眠的线程,比如目标线程调用了sleep方法而处于阻塞状态,这时候如果打断他,就会抛出InterruptedException异常。
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
TimeUnit.MILLISECONDS.sleep(100);
t1.interrupt();
}
2.2 isinterrupted
isinterrupted是Thread类的一个实例方法,主要判断目标线程(调用isinterrupted方法的Thread对象关联的线程)的中断状态。需要注意的是,该方法并不会改变目标线程的中断状态。下面的代码中,main线程在休眠了100ms后,打断了t1线程,t1线程在while循环中调用isinterrupted判断自身的中断状态,结果返回为true,由于isinterrupted方法不会清除中断标记,因此t1一直处于死循环状态,并且会一直打印Thread-0 has been interrupted.
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
while (true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println(Thread.currentThread().getName() + " has been interrupted.");
}
}
});
t1.start();
TimeUnit.MILLISECONDS.sleep(100);
t1.interrupt();
}
2.3 interrupted
interrupted是Thread类的一个静态方法,主要判断当前线程(执行Thread.interrupted方法的线程)的中断状态。与isinterrupted不同的是,如果当前线程是中断标记是true,那么执行该方法后,会将当前线程的中断状态设置为false。下面的代码中,main线程在休眠了100ms后,打断了t1线程,t1线程在while循环中调用Thread.interrupted判断自身的中断状态,结果返回为true,由于isinterrupted方法会清除中断标记,因此t1只会打印一次Thread-0 has been interrupted,并依然处于死循环状态中。
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
while (true) {
if (Thread.interrupted()) {
System.out.println(Thread.currentThread().getName() + " has been interrupted.");
}
}
});
t1.start();
TimeUnit.MILLISECONDS.sleep(100);
t1.interrupt();
}
3.总结
- interrupt是Thread类的实例方法,它的主要作用是给目标线程发送一个通知,有人希望你退出啦,同时会将目标线程的中断标志设置为true。至于目标线程如何处理,完全取决于目标线程自身。
- interrupt方法打断正在休眠的程序会抛出InterruptedException异常
- isinterrupted是Thread类的一个实例方法,主要判断目标线程的中断状态,该方法并不会改变目标线程的中断状态。
- interrupted是Thread类的一个静态方法,主要判断当前线程的中断状态。如果当前线程是中断标记是true,那么执行该方法后,会将当前线程的中断状态设置为false。