InterruptedException详解

天大地大妈咪最大 提交于 2020-02-15 22:04:11

 

1.线程为什么会抛出InterruptedException?

假如现在有两个线程1和2;线程1在正常执行,此时线程2调用了线程1的interrupt方法;代码如下:

 

@RunWith(SpringJUnit4ClassRunner.class)
public class SynchronizedTest {
    @Test
    public void testSynchronized(){
        Thread thread = new Thread(){
            public void run(){
                System.out.println(Thread.currentThread().getName()+ "线程开始了~");
                System.out.println(Thread.currentThread().getName()+ "线程结束了~");
            }
        };
        thread.start();
        System.out.println("1" + thread.isInterrupted());
        thread.interrupt();
        System.out.println("2" + thread.isInterrupted());
        System.out.println("测试结束");
    }
}


运行结果如下:

1false
2true
测试结束
Thread-2线程开始了~
Thread-2线程结束了~

可以看到,正常状态的线程,在调用interrupt方法时,并不会抛出InterruptedException,而是设置一个中断状态,这个中断状态会在何时的时候起作用,也就是中断线程,具体什么时候,我们看下《java并发编程实战》中说的:
然而如果线程处于wait,sleep,join三个方法时候,则会抛出InterruptedException。我们看下代码

public void testSynchronized(){
    Thread thread = new Thread(){
        public void run(){
            System.out.println(Thread.currentThread().getName()+ "线程开始了~");
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName()+"抛出了InterruptedException");
                System.out.println("2" + isInterrupted());
            }
            System.out.println(Thread.currentThread().getName()+ "线程结束了~");
        }
    };
    thread.start();
    System.out.println("1" + thread.isInterrupted());
    thread.interrupt();

    System.out.println("测试结束");


运行结果如下:
1false
测试结束
Thread-2线程开始了~
Thread-2抛出了InterruptedException
2false
Thread-2线程结束了~

可见:线程抛出了InterruptedException,但是线程的中断状态并没有变成true


2.如何处理InterruptedException?

一般来说,有三种做法:

(1)不做处理,直接抛出

直接抛出并不会影响线程的状态,被中断的线程还是会提前结束中断状态,继续执行

(2)捕获异常,再次调用interrupt方法,将中断状态重新设置为true;Thread.currentThread().interrupt();

这样就保留了线程原有的状态,让线程继续等待下去
(3)捕获异常,不处理;(不推荐)

3.正常运行的线程如何对中断状态做处理

由1我们知道,正常运行的线程在调用了interrupt方法后将中断状态设置为true,但此时线程的执行并未收到影响,如果要对线程的运行采取一些干预措施,则需要使用isInterrupt方法;还有个比较危险的方法 interrrupted(),只清除中断状态如:

if(thread.isInterrupt()){

//do Somethidng

}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!