java线程的中断-interrupted,isinterrupted

一.线程中断

线程中断在多线程开发中非常重要。中断线程意味着在线程结束前停止当前的操作。停止线程有许多好处。比如资源的释放,当一个线程完成了任务时,停止该线程可以释放资源。错误处理,如果某个程序发生了错误,停止线程可以防止错误蔓延。性能够优化。停止不必要的线程可以提高程序的性能等。

一.使用标志位停止线程

public class Test4 {
   public static volatile boolean IsStop = true;
    public static void main(String[] args) throws InterruptedException {

      Thread thread = new Thread(()->{
          while (IsStop){

              for(int i=0;i<100000;i++){
                  System.out.println(i);
                  try {
                      Thread.sleep(1000);
                  } catch (InterruptedException e) {
                      throw new RuntimeException(e);
                  }

              }
          }
      });
      thread.start();

      Thread.sleep(1000);
        IsStop=false;
    }
}

通过修改IsStop的值来达到停止线程的目的。这种写法是增加一个标志位,通过修改标志位的值来停止线程。试想一下如果把IsStop定义为局部变量还可以停止线程吗?
在这里插入图片描述
当我们把isStop变为局部变量,发现编译器报错,这是因为lambda表达式造成的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过对比发现lambda表达式想要修改变量这个变量必须是全局变量,这就是lambda的变量捕获。lambda表达式执行的时间比较晚。lanmba表达式看似是直接访问外部变量,其实是把外部的变量复制一份,当lambda表达式真正运行时,Lambda里面访问的局部变量可能会销毁,变量不存在,自然lambda表达式报错。要想解决这个问题让lambda表达式访问的变量是全局变量,或者是被final修饰的局部变量。

二.interrupt

手动标志位的方法太麻烦,java提供了2个类用来判断当前线程状态是否停止,interrupted,IsInterrupted。

一.interrupt

在这里插入图片描述
点开源码发现interrupted的返回值是boolean,其功能是判断当前线程是否中断。interrupted有清除标志位的特点,当连续调用2次interrupted,第一次返回中断线程true,第二次调用的时候由于第一次清除了标志位,所以第二次的返回值是false。

public class Test5 {
    public static void main(String[] args) {
    Thread thread = new Thread(()->{
        while (!Thread.currentThread().isInterrupted()) {
            System.out.println("hello");
        }
    });
    thread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        thread.interrupt();
    }
}

在这里插入图片描述
main线程运行到thread.intrrupt时,正确中断线程会返回true,Thread.currentThread().isInterrupted()会接收一个true,!Thread.currentThread().isInterrupted()会把true变为false,让循环停止。

public class Test5 {
    public static void main(String[] args) {
    Thread thread = new Thread(()->{
        while (!Thread.currentThread().isInterrupted()) {
            System.out.println("hello");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    });
    thread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        thread.interrupt();
    }
}

在这里插入图片描述
通过给线程加上sleep语句,发现编译器报错。这是因为当main线程执行到thread.intrupt的时候,恰巧thread运行到到sleep,线程正在休眠,intrupt会唤醒该线程。也就是说线程本来应该休眠1000毫秒,恰好在第10毫秒的时候,main线程运行到intrrupt,会让sleep停止休眠。这样做的好处是让程序员有更多的操作空间,让程序是否继续当前操作由程序员决定。同时sleep操作也会清除标志位从而抛出异常。要想让程序结束只需要加个break语句跳出当前循环。

  public static void main(String[] args) {
    Thread thread = new Thread(()->{
        while (!Thread.currentThread().isInterrupted()) {
            System.out.println("hello");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                break;

            }
        }
    });
    thread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        thread.interrupt();
    }
}

在这里插入图片描述
当程序让sleep抛出异常时,直接跳出循环从而让程序结束。

二.isinterrupt

在这里插入图片描述
isinterrupted和interrupted的返回值一样,interrupt判断当前线程是否中断,isterrupt判断线程是否中断。

public class Test5 { 
    public static void main(String[] args) {
   Thread thread = new Thread(()->{
       while (!Thread.currentThread().isInterrupted()){
           System.out.println("hello");
       }
   });
   thread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("第一次调用"+thread.isInterrupted());
        thread.interrupt();
        System.out.println("第二次调用"+thread.isInterrupted());
    }
}

在这里插入图片描述
第一次调用isinterrupted线程还没停止返回flase,第二次调用isinterrupted线程停止返回true.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值