Java中我们可以通过一些手段关闭一个线程。关闭一个线程有两种方式:一种是强制关闭,比如说是exit退出当前线程,stop()方法强制关闭一个线程,Interrupt方法给一个线程打上标识,如果遇到阻塞的情况下抛出InterruptedException 结束线程。
其中使用stop方法的方式强制关闭线程的方式已经不推荐了,因为可能导致一些难以预料的后果,并且这些方法在新版本的Java API中已经标注为将要过期。现在一般使用Interrupt方法的方式来关闭线程。
Java Interrupt() 方法没法强制关闭一个线程,能够做的是给线程设置中断标志。
对于处于阻塞状态的线程调用interrupt()方法的时候,会抛出一个InterruptException,并且结束线程的等待状态,直接跳转到异常处理的代码块。
也就是说,Interrupt方法可以结束处于阻塞状态的线程(比如调用sleep,join,wait方法而阻塞的线程)
我的代码和我的日志
代码:
import java.util.Date;
public class InterrupteTest {
private static Object lock = new Object();
public static void main(String[] args) {
// 测试线程调用sleep方法时被执行Interrupt
// 线程会被成功结束掉
Thread t1 = new Thread(() -> {
try {
Thread.sleep(10000);
} catch (Exception e) {
System.out.println("Thread1 is interrupted " + new Date().toString());
}
});
// 测试当一个线程处于wait状态时,被外部线程调用Interrupt方法
// 线程如果处于wait状态会被成功地结束掉
Thread t2 = new Thread(() -> {
try {
syncMethod();
} catch (Exception e) {
System.out.println("Thread2 is interrupted " + new Date().toString());
}
});
// 测试一个线程调用自己本身的interrupt()方法 -- 在线程阻塞之前调用
// 可以成功的把当前线程给结束掉
Thread t3 = new Thread(() -> {
try {
Thread.currentThread().interrupt();
syncMethod();
} catch (InterruptedException e) {
System.out.println("Thread3 is interrupted" + new Date().toString());
}
});
// 测试一个线程调用自己本身的interrupt()方法 -- 在线程阻塞之后调用
// Interrupt方法执行时,当前线程已经退出了阻塞状态,所以对当前线程没有影响
Thread t4 = new Thread(() -> {
try {
syncMethod();
Thread.currentThread().interrupt();
} catch (InterruptedException e) {
System.out.println("Thread4 is interrupted" + new Date().toString());
}
});
System.out.println("begin interrupt Thread1 " + new Date().toString());
t1.setName("Thread1");
t1.start();
t1.interrupt();
System.out.println("begin interrupt Thread2 " + new Date().toString());
t2.setName("Thread2");
t2.start();
t2.interrupt();
System.out.println("begin interrupt Thread3 " + new Date().toString());
t3.setName("Thread3");
t3.start();
System.out.println("begin interrupt Thread4 " + new Date().toString());
t4.setName("Thread4");
t4.start();
}
private static void syncMethod() throws InterruptedException {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " is calling syncMethod " + new Date().toString());
lock.wait(10000);
}
}
}
日志:
begin interrupt Thread1 Tue Jun 19 18:01:54 CST 2018
begin interrupt Thread2 Tue Jun 19 18:01:54 CST 2018
Thread1 is interrupted Tue Jun 19 18:01:54 CST 2018
begin interrupt Thread3 Tue Jun 19 18:01:54 CST 2018
Thread2 is calling syncMethod Tue Jun 19 18:01:54 CST 2018
begin interrupt Thread4 Tue Jun 19 18:01:54 CST 2018
Thread2 is interrupted Tue Jun 19 18:01:54 CST 2018
Thread4 is calling syncMethod Tue Jun 19 18:01:54 CST 2018
Thread3 is calling syncMethod Tue Jun 19 18:01:54 CST 2018
Thread3 is interruptedTue Jun 19 18:01:54 CST 2018
对上面的代码的总结:
从上面的代码中可以看到的是
1:sleep和wait方法等待的线程都可以被Interrupt掉
2:如果一个线程自己调用自己的Interrupt方法的话,最好是在阻塞之前(在本示例代码中就是要在调用wait方法之前),因为当线程阻塞掉之后就没法继续执行逻辑。必须在线程等待之前就把线程状态标识为interrupted状态。
转载请标明出处:Java 线程 Interrupt() 方法解析
文章来源: Java 线程 Interrupt() 方法解析