Java 钟的线程中断是一种线程间的协作模式,通过设置线程的中断标志不能直接终止该线程的执行,而是被中断的线程根据状态自行处理。
void interrupt() 方法:中断线程
例如:当线程 A 运行时,线程 B 可以调用线程 A 的 interrupt() 方法来设置线程 A 的中断标志为 true 并立即返回。设置标志仅仅是设置标志,线程 A 实际并没有被中断,它会继续往下执行。如果线程 A 因为调用了 wait 系列函数、join 方法或者 sleep 方法 而被挂起,这时候若线程 B 调用线程 A 的 interrupt() 方法,线程 A 会在调用这些方法的地方抛出 InterruptedException 异常而返回。
boolean isInterrupted() 方法:检测当前线程是否被中断,如果是返回 true ,否则返回 false。
boolean interrupted() 方法:检测当前线程是否被中断,如果是返回 true ,否则返回 false。
与 isInterrupted() 不同的是,该方法如果发现当前线程被中断,则会清除中断标志,并且该方法是 static 方法,可以通过 Thread 类直接调用。
在 interrupted() 内部是获取当前线程的中断标志而不是调用 interrupted() 方法的实例对象的中断标志。
线程使用 Interrupted 退出
public class InterruptedTest {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() {
public void run() {
//如果当前线程被中断则退出循环
while (!Thread.currentThread().isInterrupted()){
System.out.println(Thread.currentThread() + "hello");
}
}
});
//启动子线程
thread.start();
//主线程休眠 1s ,以便中断前让子线程输出
Thread.sleep(1000);
//中断子线程
System.out.println("主线程中断子线程");
thread.interrupt();
//等待子线程执行完毕
thread.join();
System.out.println("主线程结束");
}
}
调用阻塞线程的 interrupted() 方法,强制 sleep 方法抛出 InterruptedException 异常而返回,使线程恢复到激活状态。
public class InterruptedTest2 {
public static void main(String[] args) throws InterruptedException {
Thread threadOne = new Thread(new Runnable() {
public void run() {
try {
System.out.println("线程 one 开始睡眠 2000 s");
Thread.sleep(2000 * 1000);
System.out.println("线程 one 苏醒");
} catch (InterruptedException e) {
System.out.println("线程 one 睡眠被中断");
return;
}
System.out.println("线程 one 正常离开");
}
});
//启动线程
threadOne.start();
//确保子线程进入休眠状态
Thread.sleep(1000);
//打断子线程的休眠,让子线程从 sleep 函数返回
threadOne.interrupt();
//等待子线程执行完毕
threadOne.join();
System.out.println("主线程结束");
}
}
interrupted 和 isInterrupted 方法的区别
public class InterruptedTest3 {
public static void main(String[] args) throws InterruptedException {
Thread threadAOne = new Thread(new Runnable() {
public void run() {
for (;;){
}
}
});
//启动线程
threadAOne.start();
//设置中断标志
threadAOne.interrupt();
//获取中断标志并重置
System.out.println("isInterrupted:" + threadAOne.isInterrupted());
//获取中断标志并重置 虽然是threadAOne 但 获取的是主线程的中断标志
System.out.println("isInterrupted:" + threadAOne.interrupted());
//获取中断标志并重置
System.out.println("isInterrupted:" + Thread.interrupted());
//获取中断标志
System.out.println("isInterrupted" + threadAOne.isInterrupted());
threadAOne.join();
System.out.println("主线程结束");
}
}