前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你中断线程的方式用对了么?

你中断线程的方式用对了么?

作者头像
AI码师
发布2022-09-19 11:48:04
2450
发布2022-09-19 11:48:04
举报

启动线程

线程在初始化完成之后,调用start方法就可以启动线程.

什么是中断

中断是作为线程的一个标志位,表示运行中的线程是否被其它线程做了中断操作。中断的意思是其他线程对本线程调用interrupt方法,使其标志位变成中断。

线程自身通过检查中断标志位是否为true(通过调用isInterrupted()来进行判断),如果为true,则说明已经被其他线程做了中断操作。

如果有的方法抛出了(InterruptedException),则会在抛出此异常之前,将中断标志进行清除(Thread.interrupted()),如(sleep方法)所以这个时候你如果调用isInterrupted()方法,将会返回false。

我们可以通过一段代码进行演示:

代码语言:javascript
复制
package com.ams.thread.lesson2;

import cn.hutool.core.thread.ThreadUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * 关注微信公众号"AI码师"获取项目源码及2021面试题一套
 * 验证
 *
 * @author: AI码师
 * Date: 2021/12/21 5:19 上午
 * Description:
 */
@Slf4j
public class Example7 {

    public static void main(String[] args) {
        Thread sleepThread = new Thread(new SleepThread());
        Thread busyThread = new Thread(new BusyThread());   
        sleepThread.start();
        busyThread.start();
        ThreadUtil.sleep(3000);
        sleepThread.interrupt();
        busyThread.interrupt();
        log.info("sleepThread isInterrupted {}",sleepThread.isInterrupted());
        log.info("busyThread isInterrupted {}",busyThread.isInterrupted());
    }

    static class SleepThread implements Runnable {
        @Override
        public void run() {
           while (true){
               ThreadUtil.sleep(5000);
           }
        }
    }

    static class BusyThread implements Runnable {
        @Override
        public void run() {
           while (true){

           }
        }
    }
}

通过输出结果可以看到,sleep在抛出中断异常之前,将标志位清除了;

sleep源码是打不开的,声明了native,使用c++实现的。

这些方法已经不建议用了

中断或暂停线程的方法包括:suspend()、resume()、stop().

大家在使用这些方法去停止线程时,发现已经被标注成弃用了,为什么会被启用呢?

原因是由于调用这些方法停止线程后,线程本身所占用的资源(如suspend 不会释放锁)并不会被释放,导致资源一直不能被其它线程使用,我们可以通过下面这段代码验证下:

代码语言:javascript
复制
package com.ams.thread.lesson2;

import cn.hutool.core.thread.ThreadUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 关注微信公众号"AI码师"获取项目源码及2021面试题一套
 * 验证
 *
 * @author: AI码师
 * Date: 2021/12/21 5:19 上午
 * Description:
 */
@Slf4j
public class Example8 {

    public static void main(String[] args) {
        Thread suspendThread = new Thread(new SuspendThread());
        Thread normalThread = new Thread(new NormalThread());
        suspendThread.start();
        ThreadUtil.sleep(5000);
        normalThread.start();
        suspendThread.suspend();
        log.info("suspendThread isInterrupted");
    }

    static class SuspendThread implements Runnable {
        @Override
        public void run() {
            synchronized (Example8.class){
                while (true){
                    ThreadUtil.sleep(2000);
                    log.info("SuspendThread running");
                }
            }
        }
    }
    static class NormalThread implements Runnable {
        @Override
        public void run() {
            synchronized (Example8.class){
                log.info("NormalThread 获取锁");
            }
        }
    }
}

通过输出就够可以看到:我在调用线程的suspend()方法后,SuspendThread并没有继续打印,但是NormalThread线程却一直打印没有获得锁的日志。

那么问题就来了:如果这些终止线程的方法,都不可用,那么我怎么能优雅的终止一个线程呢?

优雅的终止线程

可以通过两种方式:

  • 通过中断标志位进行判断是否终止异常,A线程想停止B线程,则调用B线程的interrupt()方法,B线程通过在运行过程中判断中断标志位是否为true来决定是否终止线程
  • 自定义一个变量,通过外界对此变量的操作,使线程进行终止
代码语言:javascript
复制
package com.ams.thread.lesson2;

import cn.hutool.core.thread.ThreadUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 关注微信公众号"AI码师"获取项目源码及2021面试题一套
 * 验证
 *
 * @author: AI码师
 * Date: 2021/12/21 5:19 上午
 * Description:
 */
@Slf4j
public class Example9 {

    public static void main(String[] args) {
        BeautifulStopThread run = new BeautifulStopThread();
        Thread beautifulStopThread = new Thread(run);
        beautifulStopThread.start();
        ThreadUtil.sleep(5000);
//        run.stop();
        beautifulStopThread.interrupt();

    }
    static class BeautifulStopThread implements Runnable {
        boolean boolStop = false;
        @Override
        public void run() {
            synchronized (Example9.class) {
                while (!boolStop && !Thread.currentThread().isInterrupted()) {
                    log.info("BeautifulStopThread running");
                }
                log.info("BeautifulStopThread stop");
            }
        }
        public void stop() {
            this.boolStop = true;
        }
    }
}

通过结果可以看出 stop方法和interrupt方法都可以使线程优雅的停止。

关注公众号领取2021最新面试题一套和项目源码

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 乐哥聊编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 启动线程
  • 什么是中断
  • 这些方法已经不建议用了
  • 优雅的终止线程
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档