Thread.interrupted()方法的理解

 今天闲来无事为某同学解决线程的问题,写了一个通过多线程实现Count++并输出到控制台的小程序,发现自己不小心踩了一个坑。简单来说就是其中一个线程进行Count++操作,另外一个线程将Count的数字输出到控制台。其中包含了四个类:Calculate、Print、CountManager、Main,其中Calculate类是一个线程类,对count进行加一处理;Print类也是一个线程类,对Count进行打印输出;CountManager对Calculate和Print类进行管理;Main是程序入口。

 下面是各个类的代码:

public class Calculate implements Runnable {

    private CountManager manager;

    public Calculate(CountManager manager) {
        this.manager = manager;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                // 线程睡眠,等待唤醒
                synchronized (this) {
                    while (!manager.isCalculating()) {
                        this.wait();
                    }
                }

                TimeUnit.MILLISECONDS.sleep(100);
                manager.setCount(manager.getCount() + 1);
                // 唤醒其他线程
                synchronized (manager.getPrint()) {
                    manager.setCalculating(false);
                    manager.getPrint().notifyAll();
                }
            }
        } catch (Exception e) {
            System.out.println(Thread.currentThread() + "Calculate Exiting via interrupt");
        } finally {
            System.out.println("Calculate Thread: " + Thread.interrupted());
            System.out.println("Calculate Exiting");
        }
    }

}
public class CountManager {

    private volatile Integer count = 0;
    private volatile boolean calculating = false;
    private Calculate calculate;
    private Print print;
    private ExecutorService exec = Executors.newCachedThreadPool();
//    private volatile boolean shutdown = false;

    public void start() {
        calculate = new Calculate(this);
        print = new Print(this);
        exec.execute(calculate);
        exec.execute(print);
    }

    public void shutdown() {
//        shutdown = true;
        System.out.println("Shutdown");
        exec.shutdownNow();
    }

    public Integer getCount() {
        return count;
    }

    public void setCount(Integer count) {
        this.count = count;
    }

    public boolean isCalculating() {
        return calculating;
    }

    public void setCalculating(boolean calculating) {
        this.calculating = calculating;
    }

    public Calculate getCalculate() {
        return calculate;
    }

    public Print getPrint() {
        return print;
    }

//    public boolean isShutdown() {
//        return shutdown;
//    }
}
public class Print implements Runnable {

    private CountManager manager;

    public Print(CountManager manager) {
        this.manager = manager;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                System.out.println("Print Thread: " + Thread.interrupted());
                synchronized (this) {
                    // 线程睡眠等待计数完成
                    while (manager.isCalculating()) {
                        this.wait();
                    }
                }

                System.out.println(Thread.currentThread() + " " + new Date() + " " + manager.getCount());
                // 唤醒计数线程
                synchronized (manager.getCalculate()) {
                    manager.setCalculating(true);
                    manager.getCalculate().notifyAll();
                }
                // 睡眠2s
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                }
            }
        } catch (Exception e) {
            System.out.println("Print Exiting via interrupt");
        } finally {
            System.out.println("Print Exiting");
        }
    }
}
public class Main {

    public static void main(String[] args) throws InterruptedException {
        CountManager manager = new CountManager();
        manager.start();
        TimeUnit.SECONDS.sleep(10);
        manager.shutdown();
    }

}

运行Main函数之后的结果:


根据这个运行结果,发现几个问题:
1、Main函数执行了shutdown之后,程序并没有结束
2、执行了exec.shutdownNow()之后,Print和Calculate线程的Thread.interrupted()方法的返回值还是false

 首先看下Thread.interrupted()方法的注释:

 Tests whether the current thread has been interrupted. The interrupted status of the thread is cleared by this method. In other words, if this method were to be called twice in succession, the second call would return false (unless the current thread were interrupted again, after the first call had cleared its interrupted status and before the second call had examined it).

 注释上只是说明调用这个方法之后interrupted状态会被重置,但是上面的代码里面在线程interrupted之后也只调用了一次Thread.interrupted()方法,根据这个注释的说明并不能解释为什么Print和Calculate线程的interrupted状态一直是false。个人理解,线程被interrupted之后除了调用Thread.interrupted()方法会将状态重置,线程在waiting或者sleeping时interrupted,interrupted的状态也会被重置(目前并没有找到官方说明,后期如有发现,将补充说明)。之后的开发中,如果用Thread.interrupted()方法来结束线程,希望能有所警惕。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: `Thread.interrupted()` 是一个静态方法,用于检查当前线程是否被中断,并清除中断状态。它有两种用法: 1. 在线程中使用:在线程中调用 `Thread.interrupted()` 方法,可以判断当前线程是否被中断,并清除中断状态。如果当前线程被中断,那么这个方法将返回 true,否则返回 false。 2. 在其他线程中使用:如果一个线程需要中断另一个线程,可以调用另一个线程的 `interrupt()` 方法来中断它。当然,被中断的线程需要检查自己的中断状态,可以使用 `Thread.interrupted()` 方法来判断自己是否被中断。 需要注意的是,如果中断状态已经被清除(即 `Thread.interrupted()` 返回 true),那么下一次调用该方法将返回 false,因为它已经清除了中断状态。 ### 回答2: thread.interrupted() 是一个静态方法,它用于判断当前线程是否被中断,并且会清除中断状态标记。 在多线程编程中,我们可以通过调用线程的 interrupt() 方法来中断线程。当一个线程被中断时,会设置该线程的中断状态标记为 true,这可以通过 isInterrupted() 方法来获取。 而 thread.interrupted() 方法则是用来判断当前线程是否被中断的,它会返回一个布尔值来表示线程的中断状态。在判断完中断状态之后,该方法会将中断状态重新设置为 false,也就是说,如果连续多次调用 thread.interrupted() 方法,每次调用之后都会返回 false,除非在调用过程中线程又被重新中断。 使用 thread.interrupted() 方法时,需要注意以下几点: 1. thread.interrupted() 方法是一个静态方法,它只能判断当前线程是否被中断,而无法判断其他线程的中断状态。 2. 调用 thread.interrupted() 方法会清除当前线程的中断状态,如果后续还需要继续判断中断状态,可以再次调用 isInterrupted() 方法。 3. 在多线程编程中,可以通过捕获 InterruptedException 异常来处理线程被中断的情况,而不一定要使用 thread.interrupted() 方法。 综上所述,thread.interrupted() 方法用于判断当前线程是否被中断,并且会清除中断状态标记。在多线程编程中,可以根据需要选择适合的方法来处理线程中断的情况。 ### 回答3: thread.interrupted() 是 Java 中的一个方法,用于判断当前线程是否被中断,并且会清除中断状态。 当线程调用 interrupt() 方法后,该线程的中断状态会被设置为 true。而调用 thread.interrupted() 方法会检查当前线程的中断状态。 使用 thread.interrupted() 方法有以下几个特点: 1. 检查中断状态:调用 thread.interrupted() 方法可以检查当前线程的中断状态是否被设置为 true。如果中断状态为 true,则说明线程被中断了,可以根据需要进行相应的处理。 2. 清除中断状态:调用 thread.interrupted() 方法会清除当前线程的中断状态,将中断状态重新设置为 false。这样可以保证之后的判断不会再受到之前的中断状态的干扰。 3. 对于其他线程的中断状态不造成影响:thread.interrupted() 方法只会检查当前线程的中断状态,并不会影响其他线程的中断状态。即使其他线程调用了 interrupt() 方法,当前线程调用 thread.interrupted() 方法也只会检查自己的中断状态。 需要注意的是,如果中断状态为 true,表示线程被中断了,但不代表线程一定会停止运行。具体的中断处理逻辑需要开发者根据实际情况进行设计和处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值