前言
在java编程中,我们经常会调用Thread.sleep()方法使得线程停止运行一段时间,而Thread类中也提供了interrupt方法供我们去主动打断一个线程。那么线程挂起和打断的本质究竟是什么,本文就此问题作一个探究。
本文主要分为以下几个部分
1.interrupt的使用特点
2.jvm层面上interrupt方法的本质
3.ParkEvent对象的本质
4.Park()对象的本质
5.利用jni实现一个可以被打断的MyThread类
1.interrupt的使用特点
我们先看2个线程打断的示例
首先是可打断的情况:
@Test
public void interruptedTest() throws InterruptedException {
Thread sleep = new Thread(() -> {
try {
log.info("sleep thread start");
TimeUnit.SECONDS.sleep(1);
log.info("sleep thread end");
} catch (InterruptedException e) {
log.info("sleep thread interrupted");
}
}, "sleep_thread");
sleep.start();
TimeUnit.MILLISECONDS.sleep(100);
log.info("ready to interrupt sleep");
sleep.interrupt();
}
我们创建了一个“sleep”线程,其中调用了会抛出InterruptedException异常的sleep方法。“sleep”线程启动100毫秒后,主线程调用其打断方法,此时输出如下:
09:50:39.312 [sleep_thread] INFO cn.tera.thread.ThreadTest - sleep thread start
09:50:39.412 [main] INFO cn.tera.thread.ThreadTest - ready to interrupt sleep
09:50:39.412 [sleep_thread] INFO cn.tera.thread.ThreadTest - sleep thread interrupted
可以看到“sleep”线程被打断后,抛出了InterruptedException异常,并直接进入了catch的逻辑。
接着我们看一个不可打断的情况:
@Test
public void normalTest() throws InterruptedException {
Thread normal = new Thread(() -> {
log