iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java中线程中断机制的原理是什么
  • 282
分享到

Java中线程中断机制的原理是什么

2023-06-17 05:06:15 282人浏览 独家记忆
摘要

本篇文章为大家展示了Java中线程中断机制的原理是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Thread.interrupt真的能中断线程吗在平时的开发过程中,相信都会使用到多线程,在使用多

本篇文章为大家展示了Java中线程中断机制的原理是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

Thread.interrupt真的能中断线程吗

在平时的开发过程中,相信都会使用到多线程,在使用多线程时,大家也会遇到各种各样的问题,今天我们就来说说一个多线程的问题——线程中断。在 java中启动线程非常容易,大多数情况下我是让一个线程执行完自己的任务然后自己停掉,但是有时候我们需要取消某个操作,比如你在网络下载时,有时候需 要取消下载。实现线程的安全中断并不是一件容易的事情,因为Java并不支持安全快速中断线程的机制,这里估计很多同学就会说了,java不是提供了Thread.interrupt 方法中断线程吗,好吧,我们今天就从这个方法开始说起。

但是调用此方法线程真的会停止吗?我们写个demo看看就知道了。

public class Main {   private static final String TAG = "Main";   public static void main(String[] args) {     Thread t=new Thread(new NRunnable());     t.start();     System.out.println("is start.......");     try {       Thread.sleep(3000);     } catch (InterruptedException e) {      }      t.interrupt();     System.out.println("is interrupt.......");    }    public static class NRunnable implements Runnable   {      @Override     public void run() {       while(true)       {         System.out.println("我没有种中断");         try {           Thread.sleep(1000);         } catch (InterruptedException e) {          }       }     }    } }

如果interrutp方法能够中断线程,那么在打印了is interrupt…….之后应该是没有log了,我们看看执行结果吧

is start.......
我没有种中断
我没有种中断
我没有种中断
我没有种中断
我没有种中断
is interrupt.......
我没有种中断
我没有种中断
我没有种中断
我没有种中断
我没有种中断
....

通过结果可以发现子线程并没有中断

所以 Thread.interrupt() 方法并不能中断线程,该方法仅仅告诉线程外部已经有中断请求,至于是否中断还取决于线程自己。在Thread类中除了interrupt() 方法还有另外两个非常相似的方法:interrupted 和 isInterrupted 方法,下面来对这几个方法进行说明:

  • interrupt 此方法是实例方法,用于告诉此线程外部有中断请求,并且将线程中的中断标记设置为true

  • interrupted 此方法是类方法,测试当前线程是否已经中断。线程的中断状态 由该方法清除。换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在***次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外)。

  • isInterrupted 此方法是实例方法测试线程是否已经中断。线程的中断状态 不受该方法的影响。 线程中断被忽略,因为在中断时不处于活动状态的线程将由此返回 false 的方法反映出来

处理线程中断的常用方法

设置取消标记

还是用上面的例子,只不过做了些修改

public static void main(String[] args) {     NRunnable run=new NRunnable();     Thread t=new Thread(run);     t.start();     System.out.println("is start.......");     try {       Thread.sleep(3000);     } catch (InterruptedException e) {      }     run.cancel();     System.out.println("cancel ..."+System.currentTimeMillis());   }    public static class NRunnable implements Runnable   {     public boolean isCancel=false;      @Override     public void run() {       while(!isCancel)       {         System.out.println("我没有种中断");         try {           Thread.sleep(10000);         } catch (InterruptedException e) {          }       }       System.out.println("我已经结束了..."+System.currentTimeMillis());     }      public void cancel()     {       this.isCancel=true;     }    }

执行结果如下:

is start.......
我没有种中断
cancel ...1438396915809
我已经结束了...1438396922809

通过结果,我们发现线程确实已经中断了,但是细心的同学应该发现了一个问题,调用cancel方法和***线程执行完毕之间隔了好几秒的时间,也就是说线程不是立马中断的,我们下面来分析一下原因:

子线程退出的条件是while循环结束,也就是cancel标示设置为true,但是当我们调用cancel方法将calcel标记设置为true 时,while循环里面有一个耗时操作(sleep方法模拟),只有等待耗时操作执行完毕后才会去检查这个标记,所以cancel方法和线程退出中间有时 间间隔。

通过interrupt 和 isinterrupt 方法来中断线程

public static void main(String[] args) {     Thread t=new NThread();     t.start();     System.out.println("is start.......");     try {       Thread.sleep(3000);     } catch (InterruptedException e) {      }     System.out.println("start interrupt..."+System.currentTimeMillis());     t.interrupt();     System.out.println("end interrupt ..."+System.currentTimeMillis());   }    public static class NThread extends Thread   {      @Override     public void run() {       while(!this.isInterrupted())       {         System.out.println("我没有种中断");         try {           Thread.sleep(10000);         } catch (InterruptedException e) {           Thread.currentThread().interrupt();         }       }       System.out.println("我已经结束了..."+System.currentTimeMillis());     }    } }

运行结果如下:

is start.......
我没有种中断
start interrupt...1438398800110
我已经结束了...1438398800110
end interrupt ...1438398800110

这次是立马中断的,但是这种方法是由局限性的,这种方法仅仅对于会抛出InterruptedException 异常的任务时有效的,比如java中的sleep、wait 等方法,对于不会抛出这种异常的任务其效果其实和***种方法是一样的,都会有延迟性,这个例子中还有一个非常重要的地方就是cache语句中,我们调用了Thread.currentThread().interrupt() 我们把这句代码去掉,运行你会发现这个线程无法终止,因为在抛出InterruptedException 的同时,线程的中断标志被清除了,所以在while语句中判断当前线程是否中断时,返回的是false.针对InterruptedException 异常,我想说的是:一定不能再catch语句块中什么也不干,如果你实在不想处理,你可以将异常抛出来,让调用抛异常的方法也成为一个可以抛出InterruptedException 的方法,如果自己要捕获此异常,那么***在cache语句中调用 Thread.currentThread().interrupt(); 方法来让高层只要中断请求并处理该中断。

对于上述两种方法都有其局限性,***种方法只能处理那种工作量不大,会频繁检查循环标志的任务,对于第二种方法适合用于抛出InterruptedException的代码。也就是说***种和第二种方法支持的是支持中断的线程任务,那么不支持中断的线程任务该怎么做呢。

例如 如果一个线程由于同步进行I/O操作导致阻塞,中断请求不会抛出InterruptedException ,我们该如何中断此线程呢。

处理不支持中断的线程中断的常用方法

改写线程的interrupt方法

public static class ReaderThread extends Thread {    public static final int BUFFER_SIZE=512;    Socket socket;    InputStream is;     public ReaderThread(Socket socket) throws IOException    {      this.socket=socket;      is=this.socket.getInputStream();    }     @Override   public void interrupt() {      try      {        socket.close();      }catch(IOException e)      {       }finally      {        super.interrupt();      }     super.interrupt();   }    @Override   public void run() {      try      {        byte[]buf=new byte[BUFFER_SIZE];        while(true)        {          int count=is.read(buf);          if(count<0)            break;          else if(count>0)          {           }        }      }catch(IOException e)      {       }   } } }

例如在上面的例子中,改写了Thread的interrupt 方法,当调用interrupt 方法时,会关闭socket,如果此时read方法阻塞,那么会抛出IOException 此时线程任务也就结束了。

以上方法是通过改写线程的interrupt 方法实现,那么对于使用线程池的任务该怎么中断呢。

改写线程池的newTaskFor方法

通常我们向线程池中加入一个任务采用如下形式:

Future<?> future=executor.submit(new Runnable(){       @Override       public void run() {        }     });  取消任务时,调用的是future的cancel方法,其实在cancel方法中调用的是线程的interrupt方法。所以对于不支持中断的任务cancel也是无效的,下面我们看看submit方法里面干了上面吧      public Future<?> submit(Runnable task) {         if (task == null) throw new NullPointerException();         RunnableFuture<Void> ftask = newTaskFor(task, null);         execute(ftask);         return ftask;     }  这里调用的是AbstractExecutorService 的newTaskFor方法,那么我们能不能改写ThreadPoolExecutor的newTaskFor方法呢,接下来看我在处理吧  定义一个基类,所有需要取消的任务继承这个基类  public interface CancelableRunnable<T> extends Runnable {    public void cancel();   public RunnableFuture<T> newTask();  }  将上面的ReaderThread改为继承这个类   public static class ReaderThread implements CancelableRunnable<Void>   {     public static final int BUFFER_SIZE=512;     Socket socket;     InputStream is;      public ReaderThread(Socket socket) throws IOException     {       this.socket=socket;       is=this.socket.getInputStream();     }      @Override    public void run() {       try       {         byte[]buf=new byte[BUFFER_SIZE];         while(true)         {           int count=is.read(buf);           if(count<0)             break;           else if(count>0)           {            }         }       }catch(IOException e)       {        }    }      @Override     public void cancel() {       try {         socket.close();       } catch (IOException e) {        }     }      @Override     public RunnableFuture<Void> newTask() {       return new FutureTask<Void>(this,null)           {             @Override             public boolean cancel(boolean mayInterruptIfRunning) {               return super.cancel(mayInterruptIfRunning);               if(ReaderThread.this instanceof CancelableRunnable))               {                 ((CancelableRunnable)(ReaderThread.this)).cancel();               }else               {                 super.cancel(mayInterruptIfRunning);               }             }           };      } }

当你调用future的cancel的方法时,它会关闭socket,最终导致read方法异常,从而终止线程任务。

上述内容就是Java中线程中断机制的原理是什么,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注编程网精选频道。

--结束END--

本文标题: Java中线程中断机制的原理是什么

本文链接: https://www.lsjlt.com/news/287446.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java中线程中断机制的原理是什么
    本篇文章为大家展示了Java中线程中断机制的原理是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Thread.interrupt真的能中断线程吗在平时的开发过程中,相信都会使用到多线程,在使用多...
    99+
    2023-06-17
  • Java中 CAS机制的原理是什么
    Java中 CAS机制的原理是什么?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。多线程实践public class test { &nb...
    99+
    2023-06-15
  • java 中多线程的原理是什么
    今天就跟大家聊聊有关java 中多线程的原理是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1.基本概念程序、进程、线程程序(program)是为完成特定任务、用某种语言编写的一...
    99+
    2023-06-20
  • JAVA多线程之中断机制及处理中断的方法
    目录一,介绍二,中断及如何响应中断?一,介绍 这篇文章主要记录使用 interrupt() 方法中断线程,以及如何对InterruptedException进行处理。感觉对Inter...
    99+
    2023-02-13
    java多线程中断机制 java多线程中断
  • java中多线程的原理是什么
    java中多线程的原理是什么?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。java基本数据类型有哪些Java的基本数据类型分为:1、整数类型,用来表示整数的数据...
    99+
    2023-06-14
  • java中反射机制的原理是什么
    这期内容当中小编将会给大家带来有关java中反射机制的原理是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了...
    99+
    2023-06-14
  • Java中多线程的中断机制有哪些
    本篇文章为大家展示了Java中多线程的中断机制有哪些,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1、interrupt()public void interrupt()&nbs...
    99+
    2023-05-30
    java 多线程
  • SpringBoot断言机制的原理是什么
    这篇文章主要介绍“SpringBoot断言机制的原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SpringBoot断言机制的原理是什么”文章能帮助大家解决问题。JUnit 5 内置的断言可...
    99+
    2023-07-02
  • java中异常处理机制的原理是什么
    Java中的异常处理机制是基于异常类的继承关系和异常处理代码块的机制。当程序发生异常时,会抛出一个异常对象,该异常对象会沿着调用链向...
    99+
    2023-08-31
    java
  • Java中动态代理机制的原理是什么
    今天就跟大家聊聊有关Java中动态代理机制的原理是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java 动态代理机制的出现,使得 Java  开发人员不用手工编写代理...
    99+
    2023-06-17
  • Java中多线程同步的原理是什么
    Java中多线程同步的原理是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、线程的先来后到我们来举一个Dirty的例子:某餐厅的卫生间很小,几乎只能容纳一个人如厕。为了保...
    99+
    2023-06-17
  • Java中线程池的实现原理是什么
    这篇文章给大家介绍Java中线程池的实现原理是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。线程池是什么?我们可以利用java很容易创建一个新线程,同时操作系统创建一个线程也是一笔不小的开销。所以基于线程的复用,就...
    99+
    2023-05-31
    java 线程池 ava
  • Java中实现线程池的原理是什么
    Java中实现线程池的原理是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。01.***制线程的缺点多线程的软件设计方法确实可以***限度地发挥多核处理器的计算能力,提高生产...
    99+
    2023-06-16
  • Java中同步机制的底层原理是什么
    Java中同步机制的底层原理是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。同步机制源码初探ReentrantLock是我们常用的一种可重入互斥锁,是synchroni...
    99+
    2023-06-16
  • Java项目中反射机制的原理是什么
    今天就跟大家聊聊有关Java项目中反射机制的原理是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java 反射机制实例详解一、JAVA是动态语言吗?一般而言,说到动态言,都是指在...
    99+
    2023-05-31
    java 反射机制 ava
  • Java中动态绑定机制的原理是什么
    这期内容当中小编将会给大家带来有关Java中动态绑定机制的原理是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、动态绑定的过程:例子:public class Son ...
    99+
    2023-06-17
  • MySQL中复制机制的原理是什么
    MySQL中复制机制的原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。背景介绍复制,就是对数据的完整拷贝,说到为什么要...
    99+
    2024-04-02
  • Java线程的异常处理机制是什么
    本文小编为大家详细介绍“Java线程的异常处理机制是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java线程的异常处理机制是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。前言启动一个Java程序,本质...
    99+
    2023-07-02
  • Java RMI机制的原理是什么
    本篇内容主要讲解“Java RMI机制的原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java RMI机制的原理是什么”吧!Java RMIJava RMI之HelloWorld篇Ja...
    99+
    2023-06-20
  • java多线程机制是什么
    本篇内容主要讲解“java多线程机制是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java多线程机制是什么”吧!一、程序、进程、线程1.1 什么是程序程序(program):是为完成特定任...
    99+
    2023-07-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作