停止线程

2019-03-23  本文已影响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

上一篇下一篇

猜你喜欢

热点阅读