线程中止

线程中止

  • stop 中止线程,并且清除监控器的信息,但可能导致线程安全问题。JDK不建议使用
  • Destroy:JDK未实现该方法
  • interrupt:优雅的方式中断线程
  • 标志位:正确的线程中止

利用Demo演示线程中止状态

package com.study.basejava.a1_thread_status;

/**
 * 示例3 - 线程stop强制性中止,破坏线程安全的示例
 */
public class Demo3 {
    public static void main(String[] args) throws InterruptedException {
        StopThread thread = new StopThread();
        thread.start();
        // 睡眠1s 确保变量自增成功
        Thread.sleep(1000L);
        // 暂停线程
        thread.stop(); // 错误的终止
//        thread.interrupt();
        while (thread.isAlive()){
            System.out.println("线程的状态"+thread.getState().toString());
            // 确保线程已经终止
        }
        // 输出结果
        thread.print();
    }
}

package com.study.basejava.a1_thread_status;

public class StopThread extends Thread {
    private int i = 0, j = 0;

    @Override
    public void run() {
        synchronized (this){		// 原子性操作,保证线程操作不受到其他线程的干扰 正常返回结果:i 和 j 打印相同
            // 增加同步锁,确保线程安全
            ++i;
            try {
                // 睡眠10秒,模拟耗时操作
                Thread.sleep(10000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            ++j;
        }
    }

    /**
     * 打印i和j
     */
    public void print() {
        System.out.println("i=" + i + " j=" + j);
    }
}

在启动上述Demo中,理论上最终打印的 i 和 j 的数据是一致的。

  • 错误的中止方式 - stop:如果线程在睡眠期间被stop掉,会导致 i 和 j 打印的数据不一致,我们用synchronized保证原子性的目标是没有达成的,破坏了线程的线程安全。原因:利用stop停止线程,会致使正在运行的程序从中间拦腰折断,导致 i 的自增成功,j 的自增失败。这种中止线程的方式,严重的违反了我们设计线程的用意。
  • 正确的线程中止 - Interrupt
    如果目标线程在调用Object class的wait()、wait(Long)或者wait(Long,int)方法,join、join(Long、int)或sleep(long,int)方法被阻塞,那么Interrupt会生效,改线程的中端状态将被清除,抛出InterruptedException异常
    如果目标线程是被I/O或者NIO中的Channel所阻塞,同样,I/O操作会被中断或者返回特殊异常值。达到中止线程的目的。
    如果以上条件都不满足,则会设置此线程的中断状态。
    将上述实例中的stop改成Interrupt后,最终输出 i 和 j 的值相同,数据一致。
  • 标志位中断线程
    如果代码逻辑中是一个循环执行的业务,可以增加一个判断,用来控制线程执行的中止,受限于代码执行的逻辑。如 Demo4:
package com.study.basejava.a1_thread_status;
public class Demo4 {
    public volatile static boolean flag = true;

    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            try {
                while (flag){    // 判断是否运行
                    System.out.println("运行中"+Thread.currentThread().getState().toString());
                    Thread.sleep(1000L);
                }
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }).start();
        // 3秒之后,将状态标志改为False,代表不继续运行
        Thread.sleep(3000L);
        flag = false;
        System.out.println("程序运行结束"+Thread.currentThread().getState().toString());
    }
}

原文作者: 小呆呆
原文链接
版权声明: 转载请注明出处(必须保留作者署名及链接)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值