高性能编程——多线程并发编程Java基础篇之线程中止

不正确的线程中止

Stop方法

中止线程,并且清除监控器锁的信息,但是可能导致线程安全问题,JDK不推荐使用

Destroy

JDK并没有实现该方法

代码示例

为什么不推荐使用stop呢?一段代码就能解答:

package com.study.hc.thread.chapter1.thread;
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);
  }
}

执行代码:

package com.study.hc.thread;

public class Demo3 {

    public static void main(String[] args) throws InterruptedException {
        StopThread thread = new StopThread();
        thread.start();//启动线程
        Thread.sleep(1000);//主线程休眠1s,保证子线程的执行
        thread.stop();//错误的中止
        while(thread.isAlive()){
            //确保线程已中止
        }
        //输出结果
        thread.print();
    }
}

问题分析

输出结果:

i=1 j=0

很明显该答案是不符合一致性的,问题主要就处在了当++i执行完成之后没等到thread.sleep(10000)结束就中止了线程,所以++i执行了而++j并没有执行。这样的话就破坏了数据的一致性和代码的原子性

正确的终止

还是上面的代码,只需要做适当的修改即可。

package com.study.hc.thread;

public class Demo3 {

    public static void main(String[] args) throws InterruptedException {
        StopThread thread = new StopThread();
        thread.start();//启动线程
        Thread.sleep(1000);//主线程休眠1s,保证子线程的执行
        //thread.stop();//错误的中止
        thread.interrupt();//正确的终止
        while(thread.isAlive()){
            //确保线程已中止
        }
        //输出结果
        thread.print();
    }
}

interrupt

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

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

如果以上状态都不满足,则会设置线程为中断状态

通过标志位来实现对中止的控制

package com.study.hc.thread;


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.sleep(1000L);
                   }
               }catch (InterruptedException e) {
                    e.printStackTrace();
               }
        }).start();
        //3秒之后,将状态标志该为false,代表不继续运行。
        Thread.sleep(3000L);
        flag=false;
        System.out.println("程序运行结束");
    }
}

在该代码段中,加入了flag这个标志位,当它为true的时候,让程序正常运行,而当它为false的时候,则实现了中止。

发布了37 篇原创文章 · 获赞 10 · 访问量 727

猜你喜欢

转载自blog.csdn.net/weixin_41746577/article/details/103772603