美文网首页
停止线程

停止线程

作者: 迷糊小生 | 来源:发表于2019-03-23 23:05 被阅读0次

    停止一个线程意味着在线程处理完任务之前停掉正在做的操作,也就是放弃当前的操作。虽然这看起来非常简单,但是必须做好防范措施,以便达到预期的效果。

    停止一个线程可以使用Thread.stop();但是最好不要用它,因为这个方法不是安全的,而且已经被废用了,因为如果强制让线程停止则有可能使一些清理性的工作得不到完成。另外一个情况就是对锁定的对象进行了‘解锁’,导致数据得不到同步的处理,出现数据不一致的问题。

    大多数停止一个线程的操作使用的是Thread.interrupt()方法,这个方法不会终止一个正在运行的线程,仅仅是在当前线程中打上了一个停止的标记,它还需要加入一个判断才可以完成线程的停止。

    停止线程大致有三种方式:(1)当run()方法执行完后线程正常终止。(2)Thread.stop();(3)Thread.interrupt()

    判断线程是否是停止状态的方法:

    Thread.interrupted();//测试当前线程是否已经中断状态,执行完后具有将状态标志清除为false的功能
    threadObj.isInterrupted();//测试线程Thread对象是否已经中断,但不清除状态标志

        @Override
        public void run() {
            for (int i = 0; i < 20000; i++) {
                System.out.println(i);
            }
            System.out.println("END");
        }
    } 
    public class Test {
    
        public static void main(String[] args) {
            InterruptThread it = new InterruptThread();
            it.start();
            it.interrupt();
            System.out.println("main end");
            System.out.println("线程结束标记:" + it.isInterrupted());
        }
    }
    
    image.png

    由此可见Thread.interrupt()未将其线程终止,仅仅是在当前线程中打上了一个停止的标记

    异常法停止线程

       @Override
       public void run() {
           try {
               for (int i = 0; i < 2000000; i++) {
                   System.out.println(i);
                   if (this.isInterrupted()) {
                       System.out.println("线程停止,立即退出!");
                       throw new InterruptedException();
                   }
               }
               System.out.println("END");
           } catch (InterruptedException e) {
               System.out.println("InterruptThread run catch");
               e.printStackTrace();
           }
       }
    }
    public class Test {
       public static void main(String[] args) {
           InterruptThread it = new InterruptThread();
           it.start();
           it.interrupt();
           System.out.println("main end");
           System.out.println("线程结束标记:" + it.isInterrupted());
       }
    }
    
    image.png

    由于InterruptThread 类中的END并没有输出,所以由此可见在线程中断标记后,子线程停止

    在沉睡中停止

    线程在sleep()状态下停止线程(先sleep再Interrupt)

        @Override
        public void run() {
            try {
                System.out.println("run begin");
                Thread.sleep(1000);
                System.out.println("run end");
            } catch (InterruptedException e) {
                System.out.println("在沉睡中被停止:" + this.isInterrupted());
                e.printStackTrace();
            }
        }
    }
    public class Test {
        public static void main(String[] args) {
            //先沉睡再interrupt()
            InterruptThread it = new InterruptThread();
            it.start();
            it.interrupt();
            System.out.println("main end");
        }
    }
    
    image.png

    从打印的结果来看在sleep()状态下停止某一线程,会进入catch语句,并会清除标记的停止状态,使之变成false

    先Interrupt再sleep

        @Override
        public void run() {
            try {
                for (int i = 0; i < 200000; i++) {
                    System.out.println(i);
                }
                System.out.println("run begin");
                Thread.sleep(1000);
                System.out.println("run end");
            } catch (InterruptedException e) {
                System.out.println("在沉睡中被停止:" + this.isInterrupted());
                e.printStackTrace();
            }
        }
    }
    public class Test {
        public static void main(String[] args) {
            //先沉睡再interrupt()
            InterruptThread it = new InterruptThread();
            it.start();
            it.interrupt();
            System.out.println("main end");
        }
    }
    
    image.png

    由此可见无论是先sleep再Interrupt亦或者先Interrupt再sleep,都会进入catch语句,并会清除标记的停止状态,使之变成false

    相关文章

      网友评论

          本文标题:停止线程

          本文链接:https://www.haomeiwen.com/subject/mfjsvqtx.html