线程中断机制

中断机制

线程中断机制时一种协作协商机制,一个线程不应该由其他线程来强制中断或停止,而是由线程自己来决定自行停止,所以Java线程中的Thread.stop(),Thread.suspend(),Thread.resume()方法都已弃用,可以由当前线程或者是其他线程调用线程的**interrupt()**方法将线程的中断标记位设置为true。但是这样不能中断线程,仅仅只是设置了标记位的值,具体的是否中断应该由程序员自己的逻辑判定是否需要中断当前线程。例如B线程调用A线程的interrupt方法设置A线程的中断标记位为true,此时A线程并不会中断,需要在A线程的内部自己写逻辑判断是否自己需要中断


中断机制常用API方法

public void interrupt()

  • 如果线程处于正常活动状态,那么会将该线程的中断标志设置为true。仅此而已,不会对线程进行中断,具体是否会中断需要由线程自己判断,所以interrupt并不能真正中断一个线程,需要被调用的线程自己配合才行。如果线程不活动了,那调用该方法将不做任何处理
  • 如果线程处于阻塞状态(例如处于sleep,wait,join等状态),在别的线程中调用该线程的interrupt方法时,线程将立即退出阻塞状态,并抛出一个InterruptException异常,并将线程的中断标志重置为false

public static boolean interrupted()

该方法是一个静态方法,线程调用此方法时,会返回当前中断标志位的值,并将线程的中断标志设置为false,清除中断状态。

public boolean isInterrupt()

该方法用于判断线程的中断状态,返回true则表示当前线程处于中断状态,反之亦然


常见面试题

1.如何停止中断运行中的线程
  • 使用volatile关键字修饰变量,此时的变量具有可见性,即线程B修改之后线程A能够立刻检测到变量的变化

    public class Test{
        private static volatile threadInterrupt=false;
        private static final Logger log = LoggerFactory.getLogger(ThreadInterruptTest.class);
    
        public void testInterruptThread(){
            new Thread(() -> {
                while (true) {
                    if (threadInterrupt) {
                        log.info("线程{}检测到中断标识threadInterrupt为true,自行中断", Thread.currentThread().getName());
                        break;
                    }
                    log.info("线程{}继续执行", Thread.currentThread().getName());
                }
            }, "A").start();
    
            TimeUnit.MILLISECONDS.sleep(20);
    
            new Thread(() -> {
                threadInterrupt = true;
            }, "B").start();
        }
    }
    
  • 使用原子操作类AtomicBoolean,同一时刻只有一个线程在修改这个原子类对象

    public class Test{
        private static AtomicBoolean atomicInterrupt = new AtomicBoolean(false);
        private static final Logger log = LoggerFactory.getLogger(ThreadInterruptTest.class);
    
        public void testInterruptThread(){
            new Thread(() -> {
                while (true) {
                    if (atomicInterrupt.get()) {
                        log.info("线程{}检测到中断标识atomicInterrupt为true,自行中断", Thread.currentThread().getName());
                        break;
                    }
                    log.info("线程{}继续执行", Thread.currentThread().getName());
                }
            }, "A").start();
    
            TimeUnit.MILLISECONDS.sleep(20);
    
            new Thread(() -> {
                atomicInterrupt.set(true);
            }, "B").start();
        }
    }
    
  • 使用interrupt方法isInterrupted方法

    public class Test{
        private static final Logger log = LoggerFactory.getLogger(ThreadInterruptTest.class);
    
        public void testInterruptThread(){
            Thread thread1=new Thread(()->{
                while (true){
                    //isInterrupted返回线程的中断状态
                    if(Thread.currentThread().isInterrupted()){
                        log.info("线程{}检测到中断标识isInterrupted为true,自行中断", Thread.currentThread().getName());
                        break;
                    }
                    log.info("线程{}继续执行", Thread.currentThread().getName());
                }
            },"A");
            thread1.start();
            TimeUnit.MILLISECONDS.sleep(20);
            //另一个线程设置A线程的中断状态为true
            new Thread(thread1::interrupt).start();
        }
    }
    
2.当前线程的中断标识为true,是不是线程立刻停止了?

不是,只是设置了线程的中断标志位为true仅此而已,具体的线程是否停止由线程本身自己决定,所以可见哪些对线程强制进行休眠的方法例如:sleep方法已经被jdk弃用了

3.静态方法Thread.interrupted()谈谈你的理解

该方法实际上做了两次操作,一次是返回线程的中断状态,一次是将线程的中断状态重置为false

public static void testInterrupted(){
    log.info("线程当前中断标志位:{}",Thread.interrupted());
    log.info("线程当前中断标志位:{}",Thread.interrupted());
    Thread.currentThread().interrupt();
    log.info("线程当前中断标志位:{}",Thread.interrupted());
    log.info("线程当前中断标志位:{}",Thread.interrupted());
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值