泥瓦匠聊并发编程基础篇:线程中断和终止

in 编程
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

原文:www.spring4all.com

1 线程中断

1.1 什么是线程中断?

线程中断是线程的标志位属性。而不是真正终止线程,和线程的状态无关。线程中断过程表示一个运行中的线程,通过其他线程调用了该线程的 interrupt() 方法,使得该线程中断标志位属性改变。

深入思考下,线程中断不是去中断了线程,恰恰是用来通知该线程应该被中断了。具体是一个标志位属性,到底该线程生命周期是去终止,还是继续运行,由线程根据标志位属性自行处理。

1.2 线程中断操作

调用线程的 interrupt() 方法,根据线程不同的状态会有不同的结果。

下面新建 InterruptedThread 对象,代码如下:

/**
 * 一直运行的线程,中断状态为 true
 *
 * @author Jeff Lee @ bysocket.com
 * @since 2018年02月23日19:03:02
 */
public class InterruptedThread implements Runnable {

    @Override // 可以省略
    public void run() {
        // 一直 run
        while (true) {
        }
    }

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

        Thread interruptedThread = new Thread(new InterruptedThread(), "InterruptedThread");
        interruptedThread.start();

        TimeUnit.SECONDS.sleep(2);

        interruptedThread.interrupt();
        System.out.println("InterruptedThread interrupted is " + interruptedThread.isInterrupted());

        TimeUnit.SECONDS.sleep(2);
    }
}

运行 main 函数,结果如下:

InterruptedThread interrupted is true

代码详解:

另一种情况,新建 InterruptedException 对象,代码如下:

/**
 * 抛出 InterruptedException 的线程,中断状态被重置为默认状态 false
 *
 * @author Jeff Lee @ bysocket.com
 * @since 2018年02月23日19:03:02
 */
public class InterruptedException implements Runnable {

    @Override // 可以省略
    public void run() {
        // 一直 sleep
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (java.lang.InterruptedException e) {
            e.printStackTrace();
        }
    }

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

        Thread interruptedThread = new Thread(new InterruptedException(), "InterruptedThread");
        interruptedThread.start();

        TimeUnit.SECONDS.sleep(2);

        // 中断被阻塞状态(sleep、wait、join 等状态)的线程,会抛出异常 InterruptedException
        // 在抛出异常 InterruptedException 前,JVM 会先将中断状态重置为默认状态 false
        interruptedThread.interrupt();
        System.out.println("InterruptedThread interrupted is " + interruptedThread.isInterrupted());
        TimeUnit.SECONDS.sleep(2);
    }
}

运行 main 函数,结果如下:

InterruptedThread interrupted is false
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)

代码详解:

小结下线程中断:

代码:https://github.com/JeffLi1993/java-concurrency-core-learning

2 线程终止

比如在 IDEA 中强制关闭程序,立即停止程序,不给程序释放资源等操作,肯定是不正确的。线程终止也存在类似的问题,所以需要考虑如何终止线程?

上面聊到了线程中断,可以利用线程中断标志位属性来安全终止线程。同理也可以使用 boolean 变量来控制是否需要终止线程。

新建 ,代码如下:

/**
 * 安全终止线程
 *
 * @author Jeff Lee @ bysocket.com
 * @since 2018年02月23日19:03:02
 */
public class ThreadSafeStop {

    public static void main(String[] args) throws Exception {
        Runner one = new Runner();
        Thread countThread = new Thread(one, "CountThread");
        countThread.start();
        // 睡眠 1 秒,通知 CountThread 中断,并终止线程
        TimeUnit.SECONDS.sleep(1);
        countThread.interrupt();

        Runner two = new Runner();
        countThread = new Thread(two,"CountThread");
        countThread.start();
        // 睡眠 1 秒,然后设置线程停止状态,并终止线程
        TimeUnit.SECONDS.sleep(1);
        two.stopSafely();
    }

    private static class Runner implements Runnable {

        private long i;

        // 终止状态
        private volatile boolean on = true;

        @Override
        public void run() {
            while (on && !Thread.currentThread().isInterrupted()) {
                // 线程执行具体逻辑
                i++;
            }
            System.out.println("Count i = " + i);
        }

        public void stopSafely() {
            on = false;
        }
    }
}

从上面代码可以看出,通过 while (on && !Thread.currentThread().isInterrupted()) 代码来实现线程是否跳出执行逻辑,并终止。但是疑问点就来了,为啥需要 onisInterrupted() 两项一起呢?用其中一个方式不就行了吗?答案在下面

3 小结

很多好友介绍,如果用 Spring 栈开发到使用线程或者线程池,那么尽量使用框架这块提供的线程操作及框架提供的终止等

资料:
《Java 并发编程的艺术》

关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9
扫一扫关注公众号添加购物返利助手,领红包
Comments are closed.

推荐使用阿里云服务器

超多优惠券

服务器最低一折,一年不到100!

朕已阅去看看