前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java停止线程的四种方法

Java停止线程的四种方法

作者头像
凡人飞
发布2020-09-18 18:37:32
5.9K0
发布2020-09-18 18:37:32
举报
文章被收录于专栏:指缝阳光指缝阳光

一、线程停止基础知识

  • interrupted(): 测试当前线程是否已经中断。该方法为静态方法,调用后会返回boolean值。不过调用之后会改变线程的状态,如果是中断状态调用的,调用之后会清除线程的中断状态。
  • isInterrupted(): 测试线程是否已经中断。该方法由对象调用
  • interrupt(): 标记线程为中断状态,不过不会中断正在运行的线程。
  • stop(): 暴力停止线程。已弃用。

二、停止线程方法1:异常法停止

线程调用interrupt()方法后,在线程的run方法中判断当前对象的interrupted()状态,如果是中断状态则抛出异常,达到中断线程的效果。 如下示例:

MyThread.java
代码语言:javascript
复制
public class MyThread extends Thread {

    @Override
    public void run() {
        try {
            for (int i = 0; i < 500000; i++) {
                if (MyThread.interrupted()){
                    System.out.println("已经是停止状态了,我要退出了!");
                    throw new InterruptedException();
                }
                System.out.println("i = " + (i+1));
            }

            System.out.println("如果我被输出了,则代表线程没有停止");
        } catch (InterruptedException e) {
            System.out.println("在MyThread类中的run方法中被捕获");
            e.printStackTrace();
        }
    }
}
Main.java
代码语言:javascript
复制
/**
 * 根据中断状态退出for循环
 * @Author: xjf
 * @Date: 2019/5/25 13:27
 */
public class Main {

    public static void main(String[] args) {
        try {
            MyThread myThread  = new MyThread();
            myThread.start();
            Thread.sleep(100);
            myThread.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("end!");
    }
}
结果如下:
代码语言:javascript
复制
i = 19115
i = 19116
i = 19117
i = 19118
i = 19119
end!
已经是停止状态了,我要退出了!
在MyThread类中的run方法中被捕获
java.lang.InterruptedException
	at com.book.interrupt_exit.MyThread.run(MyThread.java:15)

Process finished with exit code 0

三、停止线程方法2:在沉睡中停止

  1. 先将线程sleep,然后调用interrupt标记中断状态,interrupt会将阻塞状态的线程中断。会抛出中断异常,达到停止线程的效果。如下示例:
MyThread.java
代码语言:javascript
复制
public class MyThread extends Thread {

    @Override
    public void run() {
        try {
            System.out.println("run-----------start");
            Thread.sleep(5000);
            System.out.println("run-----------end");
        } catch (InterruptedException e) {
            System.out.println("在沉睡中被停止!进入catch,线程的是否处于停止状态:" + this.isInterrupted());
            e.printStackTrace();
        }

    }
}
Main.java
代码语言:javascript
复制
public class Main {

    public static void main(String[] args) {
        try {
            MyThread myThread = new MyThread();
            myThread.start();
            Thread.sleep(2000);
            System.out.println("状态:"+MyThread.interrupted());
            myThread.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
结果
代码语言:javascript
复制
run-----------start
状态:false
java.lang.InterruptedException: sleep interrupted
在沉睡中被停止!进入catch,线程的是否处于停止状态:false
	at java.lang.Thread.sleep(Native Method)
	at com.book.sleep_interrupt.MyThread.run(MyThread.java:13)
  1. 线程先调用interrupt标记中断状态,然后线程再睡眠。会抛出中断异常,达到停止线程的效果。如下:
MyThread1.java
代码语言:javascript
复制
public class MyThread1 extends Thread {

    @Override
    public void run() {
        try {

            for (int i = 0; i < 100000; i++) {
                System.out.println("i = " + (i+1));
            }
            System.out.println("run begin");
            //interrupt是做一个中断标记,当时不会去中断正在运行的线程,当该线程处于阻塞状态时就会进行中断
            //因此,先进行interrupt后,再遇到sleep阻塞时,才会进行中断
            Thread.sleep(200000);
            System.out.println("run end");

        } catch (InterruptedException e) {
            System.out.println("先停止,再遇到了sleep! 进入catch!");
            e.printStackTrace();
        }
    }
}
Main1.java
代码语言:javascript
复制
public class Main1 {

    public static void main(String[] args) {

        MyThread1 myThread1 = new MyThread1();
        myThread1.start();
        myThread1.interrupt();
        System.out.println("end!");
    }
}
结果:
代码语言:javascript
复制
i = 99993
i = 99994
i = 99995
i = 99996
i = 99997
i = 99998
i = 99999
i = 100000
run begin
先停止,再遇到了sleep! 进入catch!
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.book.sleep_interrupt.MyThread1.run(MyThread1.java:19)

四、停止线程方法3:stop()暴力停止

线程调用stop()方法会被暴力停止,方法已弃用。该方法会有不好的后果:

  1. 强制让线程停止有可能使一些请理性的工作得不到完成。
  2. 对锁定的对象进行了“解锁”,导致数据得不到同步的处理,出现数据不一致的问题(比如一个方法加上了synchronized,并在其中进行了一个长时间的处理,而在处理结束之前该线程进行了stop(),则未完成的数据将没有进行到同步的处理)

五、停止线程方法4:使用return停止线程

  • 调用interrupt标记为中断状态后,在run方法中判断当前线程状态,如果为中断状态则return,能达到停止线程的效果。

备注:建议使用“抛异常”的方法来实现线程的停止,因为在catch块中还可以将异常向上抛,使线程停止的事件得以传播

参考:《Java多线程编程核心技术》

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/06/09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、线程停止基础知识
  • 二、停止线程方法1:异常法停止
    • MyThread.java
      • Main.java
        • 结果如下:
        • 三、停止线程方法2:在沉睡中停止
          • MyThread.java
            • Main.java
              • 结果
                • MyThread1.java
                  • Main1.java
                    • 结果:
                    • 四、停止线程方法3:stop()暴力停止
                    • 五、停止线程方法4:使用return停止线程
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档