加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java多线程技术: interrupt() 中断线程, 优雅停止线程及原理

发布时间:2020-12-15 07:41:11 所属栏目:Java 来源:网络整理
导读:MyThread.class package cn.yilong.edcsapiservice.thread; public class MyThread extends Thread { @Override public void run() { System. out .println( " 开始睡觉 " ); try { Thread.sleep( 10 ); } catch (InterruptedException e) { e.printStackTra

MyThread.class

package cn.yilong.edcsapiservice.thread;

public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("开始睡觉");
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("结束睡觉");

        synchronized (MyThread.class){
            for (int i=0; i<100; i++){
                System.out.print(i+",");
            }
            System.out.println();
            String name = Thread.currentThread().getName();
            System.out.println(name + ": " + this.isInterrupted());
            System.out.println("test--------------------");
            System.out.println();
        }

    }
}

?

Run.class

package cn.yilong.edcsapiservice.thread;

public class Run2 {

    public static void main(String[] args) {
        Thread ct = Thread.currentThread();
        ct.setName("mainThread");

        try {
            MyThread t = new MyThread();
            t.setName("myThread");
            t.start();

            t.interrupt();  // 如果t线程已经结束,再调中断方法,不做任何处理

            synchronized (MyThread.class) {
                String name = Thread.currentThread().getName();
                System.out.println(name + ": " + t.interrupted()); //虽然是t线程调用,但底层真正调用不是t,而是当前main方法的线程,执行实际操作是 Thread.currentThread().isInterrupted() 即mainThread线程
                System.out.println(t.getName() + ": " + t.isInterrupted()); 
                System.out.println("main-----------------------------");
                System.out.println();
            }


        } catch (Exception e) {
            System.out.println("main catch");
            e.printStackTrace();
        }
    }
}

?

?




mainThread: false
myThread: true
main-----------------------------

 
 

开始睡觉
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at cn.yilong.edcsapiservice.thread.MyThread.run(MyThread.java:8)
结束睡觉
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,
myThread: false
test--------------------

?



interrupt() 方法

interrupt()本质是 给调用该方法的线程做一个标记,这个标记默认初始值是: false,调用后变成: true,所以说,做标记并不能停止这个线程.  而废弃的stop()方法是直接停止这个线程. 这是根本区别.

线程对象调用interrupt()方法时,我们想中断这个线程,需要人为写逻辑进行中断,通常存在两种情况(实际还有其他,源码注释上有解释):
1. 线程状态:正在运行中,此时如果t线程调用了interrupt()方法,那么,t线程会立刻被做上标识: false变为true,(当然,如果t线程调用interrupt()前刚好正常执行结束了,
那么标记不会变更,依然时false) t线程如果还在执行中,依然继续执行下去,被标记不会受到任何影响(重点),接着,我们在t线程的执行方法run()中通过调用 interrupted()或
isInterrupted()来进行手动结束run()方法的执行. 啰嗦下: (
1) t.interrupt()执行后,打标记: false变true,run()方法中 t.interrupted()和t.isInterrupted()会获取到这个标记,值为false或true. (2) t.interrupted()方法注意两点:
1.指代当前调用的线程,也就是说,如果在mian()方法中,执行了t.interrupted()方法,实际执行的并不是t线程,而是main线程(特别注意)
2.t.interrupted()方法执行后,会返回一个结果true或false,同时它还会执行另一步操作: 将t线程标记的结果重置为默认初始值: false. 所以,不要第二次调用它.(特别注意)
(3) t.isInterrupted()方法指的就是t线程的中断标记: true,或false,它只返回结果,不会做其他的操作.

2. 线程状态: 阻塞中,比如调用了sleep(),或wait(),或join() 阻塞方法,同时,
阻塞中的t线程此时监测到自己中断标识变为了true,便抛出了InterruptedException异常,将t线程标记的结果重置为默认初始值: false (重点). 接着,我们在t线程的执行方法run()中通过try--catch捕获该异常,然后手动处理结束run()方法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读