Java多线程(7)-多线程的中断与InterruptedException

InterruptedException

在我们使用一些线程相关的方法时,例如sleep, 该方法会抛出一个InterruptedException,

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    e.printStackTrace();
}

相关的还有BlockingQueue.put/take等方法, 都会抛出InterruptedException异常,

为什么会有这个异常呢?

举一个例子,在日常的电脑使用过程中,我们可能会在电脑中搜索某个文件,这时候假设计算机开启多个线程帮我们去查找这个文件,

当其中一个线程搜索到这个文件以后,意味着其他的线程已经不需要继续查找了,所以这时候需要一个能让其他线程停止工作的功能,

在java的Thread线程类中,存在一个名叫interrupt的方法, 这个方法是用于中断调用该方法的线程,该方法是通过一个标志位的设置,让被设置的线程进行中断操作,

public static void main(String[] args) throws InterruptedException {
    Thread newThread = new Thread(() -> {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.out.println("我被中断了");
            e.printStackTrace();
        }
    });
    newThread.start();
    Thread.sleep(500);
    newThread.interrupt();
}

运行上面的代码,得到结果:

image.png

翻译一下上面代码的意思,开启一个线程,并让该线程睡眠1秒钟,随后主线程睡眠500毫秒,主线程恢复运行后,

调用了newThreadinterrupt方法,告诉它,你需要中断了,

随后newThread收到了这个消息,发生中断异常,停止睡眠,结束运行。

这里提出两个问题,

  1. 任何线程都可以被中断吗?

看如下代码:

public static void main(String[] args) throws InterruptedException {
    Thread newThread = new Thread(() -> {
        try {
            int i = 0;
            while (true) {
                i++;
                test();
            }
        } catch (InterruptedException e) {
            System.out.println("我被中断了");
            e.printStackTrace();
        }
    });
    newThread.start();
    Thread.sleep(500);
    newThread.interrupt();
}

public static void test() throws InterruptedException {

}

我们将之前的睡眠方法改造了一下,一个死循环调用了一个抛出InterruptedException却什么也没做的方法,

同时主线程休眠了500毫秒以后,发出中断信号,此时却发现,newThread线程并没有中断,而是继续在执行,

image.png

可以通过jstack命令,查看该线程的状态,在不停的RUNNABLE,说明中断信号完全没用,

image.png

此刻可以得出一个结论,并不是所有的线程都可以被中断的,会不会被中断,取决于该线程自己的决定,

在java当中,已经定义好的一些抛出InterruptedException的类库方法,会响应中断命令,进行中断,

但是一些用户自己实现的方法中,并不会。

  1. 中断只能发生在这些方法里吗?

取决于线程自己的策略, JVM中的阻塞方法都会正常响应中断信号,

什么是阻塞方法?

阻塞方法就是使得当前线程陷入一个等待的状态,并不占用CPU,而是暂停住,等一个信号让他恢复执行,或者等一个信号让他中断,例如Threadsleep方法,

还有BlockingQueue,一个java提供的阻塞队列,当生产者向队列中存放数据时,如果队列已经满了,

该步骤将进入阻塞状态,知道该队列有足够的空间,存放下要放入的数据,

当消费者消费数据时,也是一样,如果有数据时,队列将会立马返回,如果没有数据,该步骤也将进入阻塞状态。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值