interrupt的理解
言归正传,要中断一个Java线程,可调用线程类(Thread)对象的实例方法:interrupte();然而interrupte()方法并不会立即执行中断操作;
具体而言,这个方法只会给线程设置一个为true的中断标志(中断标志只是一个布尔类型的变量),而设置之后,则根据线程当前的状态进行不
同的后续操作。
-
1 线程的当前状态处于非阻塞状态,那么仅仅是线程的中断标志被修改为true而已。
-
2 线程的当前状态处于阻塞状态,那么在将中断标志设置为true后,还会有如下三种情况之一的操作:
- 如果是wait、sleep以及jion三个方法引起的阻塞,那么会将线程的中断标志重新设置为false,并抛出一个InterruptedException;
- 如果是java.nio.channels.InterruptibleChannel进行的io操作引起的阻塞,则会对线程抛出一个ClosedByInterruptedException;(待验证)
- 如果是轮询(java.nio.channels.Selectors)引起的线程阻塞,则立即返回,不会抛出异常。
-
3 如果在中断时,线程正处于非阻塞状态,则将中断标志修改为true,而在此基础上,一旦进入阻塞状态,则按照阻塞状态的情况来进行处理;
常用API
interrupt()
中断当前线程,设置中断标志true
如果当前线程正处于wait、sleep以及join三个方法引起的阻塞,将当前线程从阻塞中唤醒,并抛出抛出个InterruptedException异常,同时会将线程的中断标志重新设置为false
isInterrupted()
返回当前线程的中断状态,不清除当前中断状态
interrupted()
返回当前线程的中断状态,且清除当前中断状态(如果线程已经为true重新设置为false)。
案例
import org.junit.Test;
import java.util.concurrent.locks.LockSupport;
/**
* 当线程处于wait、sleep以及jion三个方法引起的阻塞,调用interrupt会将,那么会将线程的中断标志重新设置为false,并抛出一个InterruptedException
* 当线程处于运行状态下,用interrupt会将,那么会将线程的中断标志设置为true
* 当线程处于interrupt中断LockSupport阻塞将抛出异常,中断不会重置依旧为true
*
* 为统一我们可以捕获InterruptedException后执行interrupt,这样统一所有异常中线程的标志
*/
public class InterruptTest {
/**
* 当线程处于wait、sleep以及jion三个方法引起的阻塞,调用interrupt会将,那么会将线程的中断标志重新设置为false,并抛出一个InterruptedException
* 当线程处于运行状态下,用interrupt会将,那么会将线程的中断标志设置为true
*
* 为统一我们可以捕获InterruptedException后执行interrupt,这样统一所有异常中线程的标志
*
*/
@Test
public void test1() throws InterruptedException {
/** 启动一个线程 **/
TnterruptRunnable1 t1 = new TnterruptRunnable1();
t1.start();
TnterruptRunnable2 t2 = new TnterruptRunnable2();
t2.start();
TnterruptRunnable3 t3 = new TnterruptRunnable3();
t3.start();
Thread.sleep(1000);
t1.interrupt();
System.out.println("t1当前线程是否已经被中断:" + t1.isInterrupted());
t2.interrupt();
System.out.println("t2当前线程是否已经被中断:" + t2.isInterrupted());
t3.interrupt();
System.out.println("t3当前线程是否已经被中断:" + t3.isInterrupted());
}
/**
* 当线程处于interrupt中断LockSupport阻塞将抛出异常,中断不会重置依旧为true
*/
@Test
public void test2() throws InterruptedException {
TnterruptRunnable4 t1 = new TnterruptRunnable4("t1");
t1.start();
t1.interrupt();
Thread.sleep(5000);
}
}
class TnterruptRunnable1 extends Thread {
public void run() {
try {
while (true) {
Thread.sleep(1000l);
}
} catch (InterruptedException e) {
return;
}
}
};
class TnterruptRunnable2 extends Thread {
public void run() {
while (true) {
boolean isIn = this.isInterrupted();
if (isInterrupted()) break;
}
}
};
class TnterruptRunnable3 extends Thread {
public void run() {
try {
while (true) {
Thread.sleep(1000l);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
};
class TnterruptRunnable4 extends Thread {
public TnterruptRunnable4(String name) {
super.setName(name);
}
public void run() {
synchronized (InterruptTest.class) {
System.out.println("in " + getName());
LockSupport.park();
if (Thread.currentThread().isInterrupted()) {
System.out.println(getName() + " 被中断了!");
System.out.println(Thread.currentThread().isInterrupted());
}
}
System.out.println(getName() + " 执行结束");
}
}
网友评论