学习笔记--Java Interrupt方法

Interrupt相关方法

在Java中调用interrupt方法可以中断进程。与之相关的方法有

  • isInterrupted():返回一个boolean值,用于判断当前现成的打断状态。此方法不会重置打断标记。
  • interrupted():返回一个boolean值,用于判断当前现成的打断状态。此方法会重置打断标记。

Interrupt中断标记

需要注意的是,当调用interrupt方法大打断的时处于sleep、wait、join的方法时,会触发打断异常,但是打断标记会重置为false。示例程序如下:

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.LockSupport;

@Slf4j
public class Test1_Interrupt {
    static final Object lock = new Object();
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread current = Thread.currentThread();
                log.debug(String.valueOf(current.isInterrupted()));
            }
        }, "t1");
        Thread t2 = new Thread(() -> {
            synchronized (lock){
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread current = Thread.currentThread();
                    log.debug(String.valueOf(current.isInterrupted()));
                }
            }
        }, "t2");

        Thread t3 = new Thread(() -> {

            while (true){
                Thread current = Thread.currentThread();
                if(current.isInterrupted()){
                    log.debug(String.valueOf(current.isInterrupted()));
                    return;
                }
            }
        }, "t3");

        Thread t4 = new Thread(() -> {
            try {
                t3.join();
            } catch (InterruptedException e) {
                Thread current = Thread.currentThread();
                log.debug(String.valueOf(current.isInterrupted()));
            }
        }, "t4");

        Thread t5 = new Thread(() -> {
            log.debug("park...");
            LockSupport.park();
            LockSupport.park();
            LockSupport.park();
            log.debug("unpark...");
            log.debug("打断状态:{}", Thread.currentThread().isInterrupted());
        }, "t5");

        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();

        t1.interrupt();
        t2.interrupt();
        t4.interrupt();
        t3.interrupt();
        t5.interrupt();
    }
}

上述程序构建了四个线程:

  • t1:调用了sleep方法
  • t2:调用了wait方法
  • t3:正常运行的线程
  • t4:调用了join方法,等待线程t3结束
  • t5:调用了park、unpark方法
    输出如下
19:46:57.597 [t5] DEBUG chapter3.Test1_Interrupt - park...
19:46:57.597 [t1] DEBUG chapter3.Test1_Interrupt - false
19:46:57.597 [t4] DEBUG chapter3.Test1_Interrupt - false
19:46:57.603 [t5] DEBUG chapter3.Test1_Interrupt - unpark...
19:46:57.597 [t2] DEBUG chapter3.Test1_Interrupt - false
19:46:57.597 [t3] DEBUG chapter3.Test1_Interrupt - true
19:46:57.603 [t5] DEBUG chapter3.Test1_Interrupt - 打断状态:true

可以看到,只有正常运行的线程被打断是,park方法打断即失效,其余放啊被打断,打断标记才是true

模式之两阶段终止

目的:为了在线程被打断后能够正确的释放资源。
方法:启动监视线程,每隔一段时间判断令一线程的中断状态,若发现被打断,则启动清理程序。
流程图如下:

无异常
有异常
while true
有没有被打断
料理后事
结束循环
睡眠2s
执行监控记录
执行监控记录
设置打断标记

对应代码如下:

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Test2_TwoStageStop {
    public static void main(String[] args) {
        TPTInterrupt tpt = new TPTInterrupt();
        tpt.start();
        try {
//            Thread.sleep(200);
            Thread.sleep(2000);
            tpt.stop();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

@Slf4j
class TPTInterrupt{
    private Thread thread;
    public void start(){
        thread = new Thread(() -> {
            while(true){
                Thread current = Thread.currentThread();
                if(current.isInterrupted()){
                    log.debug("正常中断");
                    clear();
                    return;
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    log.debug("睡眠时被打断");
                    log.debug(String.valueOf(current.isInterrupted()));
                    current.interrupt();
                }
            }
        }, "监控线程");
        thread.start();
    }
    public void stop(){
        thread.interrupt();
    }
    public void clear(){
        log.debug("料理后事");
    }
}

当监视线程在睡眠过程中被打断后,需要重置打断标记(因为在睡眠过程中被打断,中断标记字会被清空)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值