• java线程中断的办法


    中断线程相关的方法

    中断线程有一些相应的方法,这里列出来一下。

    注意,如果是Thread.method(),则代表是静态方法。如果是thread.method()则代表着是类方法

    • void thread.stop()
      这个方法能中断正在运行的线程,但是已经不推荐使用了,在将来的版本或许弃用,因为强行中断运行中的线程,是不安全的。

    • void thread.interrupt()
      如果正在运行wait(),sleep(),join()这三个方法阻塞了线程,那么将会使得线程抛出InterruptedException异常,这是一个中断阻塞的过程。如果是其它的正在运行的状态,那么将不会有任何影响,也不会中断线程,或者抛出异常,只会会打上一个中断线程的标志,是否中断线程,将由程序控制。

    • boolean thread.isInterrupted()
      它会获取当前线程的标志,如果之前调用过thread.interrupt(),那么它的返回值是true。它的作用就是返回该线程是否有中断标志。多次调用这个方法的结果是一样的。

    • void Thread.interrupted()
      与前面的方法不一样的是,这是一个静态方法,代表着不需要拿到线程对象就可以直接执行,所以它的作用是返回当前线程是否有中断标志。但是它的区别是,当调用这个方法之后,会清除程序的中断标志,就是如果当前线程已中断,第一次调用这个方法的返回值是true,第二次调用这个方法的返回值为false,因为调用方法时,会清除它的中断标志。

    中断线程

    for循环标记退出

    package com.xiaojiezhu.thread;
    
    /**
     * @author xiaojie.zhu
     */
    public class ThreadBreak implements Runnable {
    
        @Override
        public void run() {
            for(int i = 0 ; i < 10000 ; i ++){
                boolean interruped = Thread.currentThread().isInterrupted();
                if(interruped){
                    //有中断标记,中断
                    break;
                }
                System.out.println(i);
            }
    
            System.out.println("over");
        }
    
    
        public static void main(String[] args) throws InterruptedException {
            Thread t = new Thread(new ThreadBreak());
            t.start();
            Thread.sleep(1);
    
            t.interrupt();
        }
    }
    
    

    打印结果如下

    44
    45
    46
    47
    over
    

    阻塞的退出线程

    只要是在运行wait(),sleep(),join()的方法,它就会声明一个InterruptedException异常,也就是意味着这些方法并不是一定能执行完成,因为当调用线程的interrupt()方法时,就会中断这个阻塞的办法,从而进入到异常中,代码如下

    package com.xiaojiezhu.thread;
    
    /**
     * @author xiaojie.zhu
     */
    public class ThreadBreak2 implements Runnable {
        @Override
        public void run() {
            try {
                Thread.sleep(20000);
                System.out.println("这段话不会输出");
            } catch (InterruptedException e) {
                //如果在sleep()的过程中调用了interrupt()方法,就会进入这里,因为会强行中断sleep()
                
                //这里打印出来的中断标记为false,因为只要进入了InterruptedException异常,中断标记就会被清除掉
                System.out.println("中断标记为:" + Thread.currentThread().isInterrupted());
                System.out.println("输出异常");
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            Thread t = new Thread(new ThreadBreak2());
            t.start();
    
            Thread.sleep(100);
    
            t.interrupt();
    
            System.out.println("over");
        }
    }
    
    

    打印结果如下

    over
    中断标记为:false
    输出异常
    java.lang.InterruptedException: sleep interrupted
    	at java.lang.Thread.sleep(Native Method)
    	at com.xiaojiezhu.thread.ThreadBreak2.run(ThreadBreak2.java:10)
    	at java.lang.Thread.run(Thread.java:748)
    
    

    注意:因为只要进入了InterruptedException异常,中断标记就会被清除掉

    这里会衍生出另一种情况,就是如果在进入阻塞方法之前,就有了中断标记呢?会发生什么,就如下的代码:

    for(int i = 0 ; i < 10000 ; i ++){
        System.out.println(i);
    }
    try {
        System.out.println("开始sleep");
        Thread.sleep(20000);
        System.out.println("结束sleep");
    
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    

    实际上它会先执行完上面的for循环,因为for循环中是无法中止的,在进入sleep()的时候,瞬间就抛出异常

    完整的测试代码如下

    package com.xiaojiezhu.thread;
    
    /**
     * @author xiaojie.zhu
     */
    public class ThreadBreak3 implements Runnable {
    
        @Override
        public void run() {
            for(int i = 0 ; i < 10000 ; i ++){
                System.out.println(i);
            }
            try {
                System.out.println("开始sleep");
                Thread.sleep(20000);
                System.out.println("结束sleep");
    
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    
        public static void main(String[] args) {
            Thread thread = new Thread(new ThreadBreak3());
            thread.start();
    
            thread.interrupt();
        }
    }
    
    

    打印结果如下

    9997
    9998
    9999
    开始sleep
    java.lang.InterruptedException: sleep interrupted
    	at java.lang.Thread.sleep(Native Method)
    	at com.xiaojiezhu.thread.ThreadBreak3.run(ThreadBreak3.java:15)
    	at java.lang.Thread.run(Thread.java:748)
    

    使用stop()方法停止线程

    thread.stop()方法是一个不安全的方法,已经不推荐使用了,但是在目前的代码中,还能正常使用,我们不推荐这样使用,但是这里介绍一下

    package com.xiaojiezhu.thread;
    
    /**
     * @author xiaojie.zhu
     */
    public class ThreadBreak4 implements Runnable {
        @Override
        public void run() {
            System.out.println("进入线程");
            try {
                Thread.sleep(20000);
                System.out.println("结束线程");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    
        public static void main(String[] args) {
            Thread t  = new Thread(new ThreadBreak4());
            t.start();
            try {
                Thread.sleep(200);
    
                t.stop();
    
                System.out.println("over");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    打印结果如下

    进入线程
    over
    
  • 相关阅读:
    Windows下做7层软负载方案分析
    蛙蛙推荐:C语言入门之二——编写第一个有意义的小程序
    蛙蛙推荐:C语言入门之一——Linux下的C开发环境搭建小节
    蛙蛙推荐:动手做个网页游戏五子棋
    学习园地:微博项目
    com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field 异常 规格严格
    PostgreSQL Update 根据B表更新A表 规格严格
    SQL 删除重复数据[转] 规格严格
    ntoskrnl.exe占用cpu高 规格严格
    PostgreSQL中RECURSIVE递归查询使用总结[转] 规格严格
  • 原文地址:https://www.cnblogs.com/zhuxiaojie/p/9385136.html
Copyright © 2020-2023  润新知