优雅的停止线程

1.停止线程的方法

停止线程的方法有3种:

1.使用退出标志使线程退出

2.使用stop()方法强制终止线程,当方法不推荐 【过期方法】

3.使用interrupt()方法中中断线程

2.interrupt方法

interrupt方法的使用效果并不是马上停止线程,而是做一个停止标记

3.具体如何停止线程?

在《java多线程编程核心技术》这本书中描述了以下方法

1.异常法(推荐)

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();
        }
    }
}
/**
 * 根据中断状态退出for循环
 */
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!");
    }
}

结果如下:

2.sleep状态下停止线程

睡眠中断又分2种情况:

  1. 先将线程sleep,然后调用interrupt标记中断状态,interrupt会将阻塞状态的线程中断。会抛出中断异常,达到停止线程的效果。
  2. 线程先调用interrupt标记中断状态,然后线程再睡眠。会抛出中断异常,达到停止线程的效果。

1.先sleep

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();
        }

    }
}

 

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();
        }
    }
}

 

结果如下:

2.先标记中断

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();
        }
    }
}
public class Main1 {

    public static void main(String[] args) {

        MyThread1 myThread1 = new MyThread1();
        myThread1.start();
        myThread1.interrupt();
        System.out.println("end!");
    }
}

结果如下:

3.stop暴力停止(不推荐)

4.return语句停止线程

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

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

猜你喜欢

转载自blog.csdn.net/f_a_ker/article/details/114109996