多线程之中断详解

 现在提供一下线程中断的几种方法

  • Stop() 方法

         stop() 废弃方法,开发中不要使用。因为一调用,线程就立刻停止,此时有可能引发相应的线程安全性问题

下面根据代码来具体看一下:


public class UnSaveWithStopDemo extends Thread {
	private int i = 0;
	private int j = 0;

	@Override
	public void run() {
		i++;
		try {
			Thread.sleep(5000L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		j++;
	}

	public void printf() {
		System.out.println("i的值=====" + i);
		System.out.println("j的值=====" + j);
	}

	public static void main(String[] args) throws InterruptedException {

		UnSaveWithStopDemo myThread = new UnSaveWithStopDemo();
		myThread.start();
		Thread.sleep(1000L);
		myThread.stop();
		myThread.printf();

	}

}

最终输出为:

这个与我们的预期:j=1,i=1,就不相符了。

  • interrup

线程的thread.interrupt()方法是中断线程,将会设置该线程的中断状态,即设置为true。中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true)。它并不像stop方法那样会中断一个正在运行的线程。

public void run() {
    try {
        ...
        /*
         * 不管循环里是否调用过线程阻塞的方法如sleep、join、wait,这里还是需要加上
         * !Thread.currentThread().isInterrupted()条件,虽然抛出异常后退出了循环,显
         * 得用阻塞的情况下是多余的,但如果调用了阻塞方法但没有阻塞时,这样会更安全、更及时。
         */
        while (!Thread.currentThread().isInterrupted()&& more work to do) {
            do more work 
        }
    } catch (InterruptedException e) {
        //线程在wait或sleep期间被中断了
    } finally {
        //线程结束前做一些清理工作
    }
}

 

上面是while循环在try块里,如果try在while循环里时,因该在catch块里重新设置一下中断标示,因为抛出InterruptedException异常后,中断标示位会自动清除,此时应该这样:

public void run() {
    while (!Thread.currentThread().isInterrupted()&& more work to do) {
        try {
            ...
            sleep(delay);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();//重新设置中断标示
        }
    }
}

底层中断异常处理方式

不要在你的底层代码里捕获InterruptedException异常后不处理,会处理不当,如下:

void run(){
    ...
    try{
        sleep(delay);
    }catch(InterruptedException e){}//不要这样做
    ...
}

如果你不知道抛InterruptedException异常后如何处理,那么你有如下好的建议处理方式:

1、在catch里面设置Thread.currentThread().interrupt(),设置中断标志,让外界通过判断Thread.currentThread().isInterrupted()标示来决定是否终止线程还是继续下去,应该这样做:

void mySubTask() {
    ...
    try {
        sleep(delay);
    } catch (InterruptedException e) {
        Thread.currentThread().isInterrupted();
    }
    ...
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值