Java--多线程之终止/中断线程(二)

本文详细介绍了Java中如何终止线程,包括使用退出标志、弃用的stop方法以及推荐的interrupt方法。强调了interrupt方法的作用在于中断线程的阻塞状态,并非强制终止执行,同时讨论了线程中断的判断与处理。
摘要由CSDN通过智能技术生成

Java--多线程之并发,并行,进程,线程(一)_MinggeQingchun的博客-CSDN博客

Java--多线程之join,yield,sleep;线程优先级;定时器;守护线程(三)_MinggeQingchun的博客-CSDN博客

Java--多线程之synchronized和lock;死锁(四)_MinggeQingchun的博客-CSDN博客

Java--多线程之生产者消费者模式;线程池ExecutorService(五)_MinggeQingchun的博客-CSDN博客

Java 中有以3 种方法可以终止/中断正在运行的线程:

1、使用退出标志,使线程正常退出,也就是当 run() 方法完成后线程中止

2、使用 stop() 方法强行终止线程,但是不推荐使用这个方法,该方法已被弃用

3、使用 interrupt() 方法中断线程(只是中断线程执行,终止线程的睡眠(唤醒),并未终止线程)

1、标志位

定义一个boolean型的标志位,在线程的run方法中根据这个标志位是true还是false来判断是否退出

/**
 * 使用标志位终止线程
 * */
public class ThreadStop {
    public static void main(String[] args) {
        ThreadStopRunnable runnable = new ThreadStopRunnable();
        Thread t = new Thread(runnable);
        t.setName("t");
        t.start();

        try {
            Thread.sleep(1000 * 5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //执行5秒之后终止线程,终止t线程的执行,将标记修改为false即可
        runnable.runFlag = false;

        for (int i = 1; i <= 100; i++) {
            System.out.println(Thread.currentThread().getName() + "---->" + i);
        }
    }
}

class ThreadStopRunnable implements Runnable {
    //volatile修饰符用来保证其它线程读取的总是该变量的最新的值
    public volatile boolean runFlag = true;

    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            if (runFlag){
                System.out.println(Thread.currentThread().getName() + "---->" + i);

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }else {
                //执行终止线程之前的代码,如保存数据等

                return;
            }
        }
    }
}

2、 stop() 方法

通过查看 JDK 的 API,我们会看到 java.lang.Thread 类型提供了一系列的方法如 start()、stop()、resume()、suspend()、destory()等方法来管理线程。但是除了 start() 之外,其它方法都被声名为已过时(deprecated)

虽然 stop() 方法确实可以停止一个正在运行的线程,但是这个方法是不安全的,而且该方法已被弃用,最好不要使用它。
JDK 文档中还引入用一篇文章来解释了弃用这些方法的原因:《Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?》

为何弃用stop:

1、调用 stop() 方法会立刻停止 run() 方法中剩余的全部工作,包括在 catch 或 finally 语句中的,并抛出ThreadDeath异常(通常情况下此异常不需要显示的捕获),因此可能会导致一些清理性的工作的得不到完成,如文件,数据库等的关闭

2、调用 stop() 方法会立即释放该线程所持有的所有的锁,导致数据得不到同步,出现数据不一致的问题

// thread.stop()强行终止t线程
thread.stop();

3、interrupt() 方法中断线程

t.interrupt()方法只是中断t线程的睡眠(依靠了Java的异常处理机制),唤醒线程;t.interrupt()方法不是中断线程的执行,是唤醒线程

/**
 线程sleep睡眠,唤醒一个正在睡眠的线程
    t.interrupt();
    中断t线程的睡眠(这种中断睡眠的方式依靠了Java的异常处理机制)
    注:这个不是中断线程的执行,是终止线程的睡眠
 */
public class ThreadWakeup {
    public static void main(String[] args) {
        Thread t = new Thread(new SleepRunnable());
        t.setName("t");
        t.start();

        try {
            //5秒之后就可以输出  “t----end”;
            Thread.sleep(1000 * 5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        /**
         * 中断t线程的睡眠(这种中断睡眠的方式依靠了Java的异常处理机制)
         *
         * t.interrupt(); 采用了Java的异常处理机制,如果不想输出异常,可以注释掉e.printStackTrace();
         *
         * t----begin
         * java.lang.InterruptedException: sleep interrupted
         * 	at java.lang.Thread.sleep(Native Method)
         * 	at thread.sleep.SleepRunnable.run(ThreadWakeup.java:35)
         * 	at java.lang.Thread.run(Thread.java:748)
         * t----end
         * */
        t.interrupt();
    }
}

class SleepRunnable implements Runnable{

    /**
     * run()当中的异常不能throws,只能try catch
     * 因为run()方法在父类中没有抛出任何异常,子类不能比父类抛出更多的异常
     */
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "----begin");
        try {
            Thread.sleep(1000 * 60 * 60 * 24);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //睡眠一天后才可以执行
        System.out.println(Thread.currentThread().getName() + "----end");
    }

    // 其它方法可以throws
    /*public void doOther() throws Exception{
    }*/
}

注:

在Thread类中有两个方法可以判断线程是否通过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted可以用来判断其他线程是否被中断

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值