当前位置:首页 > Java > 正文内容

Java多线程-线程中止

flowstone6年前 (2019-08-26)Java483

不正确的线程中止-Stop

Stop:中止线程,并且清除监控器锁的信息,但是可能导致 线程安全问题,JDK不建议用。 Destroy: JDK未实现该方法。


/**
 * @author simon
 */
public class StopThread extends Thread {
    private int i = 0, j = 0;
    @Override
    public void run() {
        synchronized (this) {
            // 增加同步锁,确保线程安全
            ++i;
            try {
                // 休眠10秒,模拟耗时操作
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            ++j;
        }
    }
    /** * 打印i和j */
    public void print() {
        System.out.println("i=" + i + " j=" + j);
    }
}
/**
 * @author simon
 * 示例3 - 线程stop强制性中止,破坏线程安全的示例
 */
public class Demo {
    public static void main(String[] args) throws InterruptedException {
        StopThread thread = new StopThread();
        thread.start();
        // 休眠1秒,确保i变量自增成功
        Thread.sleep(1000);
        // 暂停线程
        thread.stop(); // 错误的终止
        //thread.interrupt(); // @正确终止
        while (thread.isAlive()) {
            // 确保线程已经终止
        } // 输出结果
        thread.print();
    }
}


理想状态:要么自增成功i=1, j=1,要么自增失败i=0, j=0 真正程序执行结果:i=1, j=0

没有保证同步代码块里面数据的一致性,破坏了线程安全 stop方法直接停止线程

正确的线程中止-interrupt

如果目标线程在调用Object class的wait()、wait(long)或wait(long, int)方法、join()、join(long, int)或sleep(long, int)方法时被阻塞,那么Interrupt会生效,该线程的中断状态将被清除,抛出InterruptedException异常。

如果目标线程是被I/O或者NIO中的Channel所阻塞,同样,I/O操作会被中断或者返回特殊异常值。达到终止线程的目的。

如果以上条件都不满足,则会设置此线程的中断状态。

对Demo中的示例,stop()改成interrupt()后,最终输出为"i=1 j=1",数据一致。

正确的线程中止-标志位

/** 通过状态位来判断 */
public class Demo4 extends Thread {
  public volatile static boolean flag = true;

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

在上方代码逻辑中,增加一个判断,用来控制线程执行的中止。


扫描二维码推送至手机访问。

版权声明:本文由薛尧的博客发布,如需转载请注明出处。

本文链接:https://flowstone.sourceforge.io/?id=50

分享给朋友:

相关文章

Java Random入门

什么是Random?当用户要产生一个随机数,java本身提供了丰富的Random类。用户可以根据需求创建Random对象,根据Random类下的方法创建特殊的随机数。如何创建Random?首先用户要创建一个Random对象Random&nb...

Ehcache缓存简单使用

SPRING整合EHCACHE1.引入坐标pom.xml<!-- ehcache的缓存框架 --> <dependency>     <group...

IntelliJ IDEA技巧一之隐藏.idea目录

问题场景通过IntelliJ IDEA软件创建Java Web项目时,项目目录中总会生成.idea配置目录并在软件界面里显示,影响项目美感,如何在软件界面中隐藏.idea目录呢?解决方法打开IDEA软件的设置(Mac是Preferences...

ElasticSearch从入门到放弃(一)-安装&运行

这几天看到新闻,说ElasticSearch上市了,真的没有想到这个非常流行的开源项目竟然上市了,这个公司的程序员都走上了财务自由的道路。 以前用过ElasticSearch全文搜索引擎,但是时间长也忘记了差不多了,以前而且还是用的老版本,...

Java内存缓存-通过Map定制简单缓存

缓存在程序中,缓存是一个高速数据存储层,其中存储了数据子集,且通常是短暂性存储,这样日后再次请求此数据时,速度要比访问数据的主存储位置快。通过缓存,可以高效地重用之前检索或计算的数据。为什么要用缓存场景在Java应用中,对于访问频率高,更新...

Java多线程-线程状态

线程状态6个状态定义:java.lang.Thread.StateNew: 尚未启动的线程的线程状态。Runnable: 可运行线程的线程状态,等待CPU调度。Blocked: 线程阻塞等待监视器锁定的线程状态。处于synchronized...