「java线程的中断方法」java线程的中断方法是什么

博主:adminadmin 2023-01-26 11:09:11 328

本篇文章给大家谈谈java线程的中断方法,以及java线程的中断方法是什么对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

Java如何中断一个正在运行的线程

程序是很简易的 然而 在编程人员面前 多线程呈现出了一组新的难题 如果没有被恰当的解决 将导致意外的行为以及细微的 难以发现的错误

在本篇文章中 我们针对这些难题之一 如何中断一个正在运行的线程

背景中断(Interrupt)一个线程意味着在该线程完成任务之前停止其正在进行的一切 有效地中止其当前的操作 线程是死亡 还是等待新的任务或是继续运行至下一步 就取决于这个程序 虽然初次看来它可能显得简单 但是 你必须进行一些预警以实现期望的结果 你最好还是牢记以下的几点告诫

首先 忘掉Thread stop方法 虽然它确实停止了一个正在运行的线程 然而 这种方法是不安全也是不受提倡的 这意味着 在未来的JAVA版本中 它将不复存在

一些轻率的家伙可能被另一种方法Thread interrupt所迷惑 尽管 其名称似乎在暗示著什么 然而 这种方法并不会中断一个正在运行的线程(待会将进一步说明) 正如Listing A中描述的那样 它创建了一个线程 并且试图使用Thread interrupt方法停止该线程 Thread sleep()方法的调用 为线程的初始化和中止提供了充裕的时间 线程本身并不参与任何有用的操作

class Example extends Thread {            boolean stop=false;            public static void main( String args[] ) throws Exception {            Example thread = new Example ();            System out println( Starting thread );            thread start();            Thread sleep( );            System out println( Interrupting thread );            thread interrupt();            Thread sleep( );            System out println( Stopping application );            //System exit( );            }            public void run() {            while(!stop){            System out println( Thread is running );            long time = System currentTimeMillis();            while((System currentTimeMillis() time )) {            }            }            System out println( Thread exiting under request );            }            }

如果你运行了Listing A中的代码 你将在控制台看到以下输出

Starting thread Thread is running Thread is running Thread is running Interrupting thread Thread is running Thread is running Thread is running Stopping application Thread is running Thread is running Thread is running

甚至 在Thread interrupt()被调用后 线程仍然继续运行

真正地中断一个线程

中断线程最好的 最受推荐的方式是 使用共享变量(shared variable)发出信号 告诉线程必须停止正在运行的任务 线程必须周期性的核查这一变量(尤其在冗余操作期间) 然后有秩序地中止任务 Listing B描述了这一方式

Listing Bclass Example  extends Thread {  volatile boolean stop = false;  public static void main( String args[] ) throws Exception {    Example  thread = new Example ();   System out println(  Starting thread  );   thread start();   Thread sleep(   );   System out println(  Asking thread to stop  );   thread stop = true;   Thread sleep(   );   System out println(  Stopping application  );   //System exit(   );  }  public void run() {    while ( !stop ) {     System out println(  Thread is running  );      long time = System currentTimeMillis();      while ( (System currentTimeMillis() time   )  (!stop) ) {      }    }   System out println(  Thread exiting under request  );  }}

运行Listing B中的代码将产生如下输出(注意线程是如何有秩序的退出的)

Starting thread Thread is running Thread is running Thread is running Asking thread to stop Thread exiting under request Stopping application

虽然该方法要求一些编码 但并不难实现 同时 它给予线程机会进行必要的清理工作 这在任何一个多线程应用程序中都是绝对需要的 请确认将共享变量定义成volatile 类型或将对它的一切访问封入同步的块/方法(synchronized blocks/methods)中

到目前为止一切顺利!但是 当线程等待某些事件发生而被阻塞 又会发生什么?当然 如果线程被阻塞 它便不能核查共享变量 也就不能停止 这在许多情况下会发生 例如调用Object wait() ServerSocket accept()和DatagramSocket receive()时 这里仅举出一些

他们都可能永久的阻塞线程 即使发生超时 在超时期满之前持续等待也是不可行和不适当的 所以 要使用某种机制使得线程更早地退出被阻塞的状态

很不幸运 不存在这样一种机制对所有的情况都适用 但是 根据情况不同却可以使用特定的技术 在下面的环节 我将解答一下最普遍的例子

使用Thread interrupt()中断线程

正如Listing A中所描述的 Thread interrupt()方法不会中断一个正在运行的线程 这一方法实际上完成的是 在线程受到阻塞时抛出一个中断信号 这样线程就得以退出阻塞的状态 更确切的说 如果线程被Object wait Thread join和 Thread sleep三种方法之一阻塞 那么 它将接收到一个中断异常(InterruptedException) 从而提早地终结被阻塞状态

因此 如果线程被上述几种方法阻塞 正确的停止线程方式是设置共享变量 并调用interrupt()(注意变量应该先设置) 如果线程没有被阻塞 这时调用interrupt()将不起作用 否则 线程就将得到异常(该线程必须事先预备好处理此状况) 接着逃离阻塞状态 在任何一种情况中 最后线程都将检查共享变量然后再停止 Listing C这个示例描述了该技术

Listing Cclass Example  extends Thread {  volatile boolean stop = false;  public static void main( String args[] ) throws Exception {   Example  thread = new Example ();   System out println(  Starting thread  );   thread start();   Thread sleep(   );   System out println(  Asking thread to stop  );   thread stop = true;//如果线程阻塞 将不会检查此变量   thread interrupt();   Thread sleep(   );   System out println(  Stopping application  );   //System exit(   );  }  public void run() {    while ( !stop ) {     System out println(  Thread running  );      try {      Thread sleep(   );      } catch ( InterruptedException e ) {      System out println(  Thread interrupted  );      }    }   System out println(  Thread exiting under request  );  }}

一旦Listing C中的Thread interrupt()被调用 线程便收到一个异常 于是逃离了阻塞状态并确定应该停止 运行以上代码将得到下面的输出

Starting thread Thread running Thread running Thread running Asking thread to stop Thread interrupted Thread exiting under request Stopping application

中断I/O操作

然而 如果线程在I/O操作进行时被阻塞 又会如何?I/O操作可以阻塞线程一段相当长的时间 特别是牵扯到网络应用时 例如 服务器可能需要等待一个请求(request) 又或者 一个网络应用程序可能要等待远端主机的响应

如果你正使用通道(channels)(这是在Java 中引入的新的I/O API) 那么被阻塞的线程将收到一个 ClosedByInterruptException异常 如果情况是这样 其代码的逻辑和第三个例子中的是一样的 只是异常不同而已

但是 你可能正使用Java 之前就存在的传统的I/O 而且要求更多的工作 既然这样 Thread interrupt()将不起作用 因为线程将不会退出被阻塞状态 Listing D描述了这一行为 尽管interrupt()被调用 线程也不会退出被阻塞状态

Listing Dimport java io *;class Example  extends Thread {  public static void main( String args[] ) throws Exception {    Example  thread = new Example ();   System out println(  Starting thread  );   thread start();   Thread sleep(   );   System out println(  Interrupting thread  );   thread interrupt();   Thread sleep(   );   System out println(  Stopping application  );   //System exit(   );  }  public void run() {   ServerSocket socket;    try {      socket = new ServerSocket( );    } catch ( IOException e ) {     System out println(  Could not create the socket  );      return;    }    while ( true ) {     System out println(  Waiting for connection  );      try {       Socket sock = socket accept();      } catch ( IOException e ) {      System out println(  accept() failed or interrupted  );      }    }  }}

很幸运 Java平台为这种情形提供了一项解决方案 即调用阻塞该线程的套接字的close()方法 在这种情形下 如果线程被I/O操作阻塞 该线程将接收到一个SocketException异常 这与使用interrupt()方法引起一个InterruptedException异常被抛出非常相似

唯一要说明的是 必须存在socket的引用(reference) 只有这样close()方法才能被调用 这意味着socket对象必须被共享 Listing E描述了这一情形 运行逻辑和以前的示例是相同的

Listing Eimport  *;import java io *;class Example  extends Thread {  volatile boolean stop = false;  volatile ServerSocket socket;  public static void main( String args[] ) throws Exception {    Example  thread = new Example ();   System out println(  Starting thread  );   thread start();   Thread sleep(   );   System out println(  Asking thread to stop  );   thread stop = true;   thread socket close();   Thread sleep(   );   System out println(  Stopping application  );   //System exit(   );  }  public void run() {    try {      socket = new ServerSocket( );    } catch ( IOException e ) {     System out println(  Could not create the socket  );      return;    }    while ( !stop ) {     System out println(  Waiting for connection  );      try {       Socket sock = socket accept();      } catch ( IOException e ) {      System out println(  accept() failed or interrupted  );      }    }   System out println(  Thread exiting under request  );  }}

以下是运行Listing E中代码后的输出

Starting thread Waiting for connection Asking thread to stop accept() failed or interrupted Thread exiting under request Stopping application

    多线程是一个强大的工具 然而它正呈现出一系列难题 其中之一是如何中断一个正在运行的线程 如果恰当地实现 使用上述技术中断线程将比使用Java平台上已经提供的内嵌操作更为简单 lishixinzhi/Article/program/Java/gj/201311/27481

Java中如何中断线程

1: 给你的线程类一个标识符,然后在循环中对这个标志做判断,如果为false则跳出循环,自动结束线程(线程在run()里面执行完就自动关闭了),而你可以再线程外对这个标识符做控制。2: 对线程对象调用interrupt(),这样在run中使用sleep,wait等方法时自动抛出一个InterruptedException异常,在catch里面可以跳出循环。

如何停止一个Java线程

1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。

2. 使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。

3. 使用interrupt方法中断线程。

1. 使用退出标志终止线程

当run方法执行完后,线程就会退出。但有时run方法是永远不会结束的。如在服务端程序中使用线程进行监听客户端请求,或是其他的需要循环处理的任务。在这种情况下,一般是将这些任务放在一个循环中,如while循环。如果想让循环永远运行下去,可以使用while(true){……}来处理。但要想使while循环在某一特定条件下退出,最直接的方法就是设一个boolean类型的标志,并通过设置这个标志为true或false来控制while循环是否退出。下面给出了一个利用退出标志终止线程的例子。

java中终止线程的方法?

在Java的多线程编程中,java.lang.Thread类型包含了一些列的方法start(),stop(),stop(Throwable)andsuspend(),destroy()andresume()。通过这些方法,我们可以对线程进行方便的操作,但是这些方法中,只有start()方法得到了保留。本文是海文国际小编搜索整理的关于JAVA中终止线程的方法,供参考复习,希望对大家有所帮助!

如果真的需要终止一个线程,可以使用以下几种方法:

1、让线程的run()方法执行完,线程自然结束。(这种方法最好)

2、通过轮询和共享标志位的方法来结束线程,例如while(flag){},flag的初始值设为真,当需要结束时,java课程培训机构建议将flag的值设为false。(这种方法也不很好,因为如果while(flag){}方法阻塞了,则flag会失效)

Java 基本功之中断线程的理解

设想这样的情景 我们的应用在某一个时间段内 需要一个子线程不停的在后台运行 这可能是一个下载过程 是一个对服务端socket的监听 也可能是一个绘图的计算过程 当我们想要终止线程的时候 我们会怎样做呢?是设定一个标志变量来控制跳出循环?还是使用thread stop()?又或者是设置thread = null?

有的时候我们需要一种规范的思路 使用规范的方法来解决一类问题

我们首先要明白 线程终止的条件 有三种情况

当线程的run方法执行方法体中最后一条语句后

当执行retutrn语句返回时

当出现了在方法中没有捕获的异常时

在Java的早期版本中 还有一个stop方法 其他线程可以调用它终止线程 但是这个方法已经被弃用了 所以还在用的同学就不要继续用了

我们的正确思路是 使用interrupt方法来终止我们的线程

首先要理解interrupt方法做了什么 每一个线程都有一个中断状态 这是一个boolean标志 当线程调用了interrupt方法时 这个中断状态就会被置位 如果我们要检查中断状态 可以使用Thread currentThread() isInterrupted()来获得是否中断

但是如果线程被阻塞了(sleep or wait) 当我们调用了interrupt方法的时候 就会产生InterruptedException异常 这是我们可以利用的地方

同样的 如果中断状态先被置位了 然后我们调用了sleep方法 线程不会休眠 相反 它将清除中断状态 然后抛出InterruptedException

我们调用了interrupt并不意味着线程会终止 线程是否会终止 以及会如何继续 是程序员来控制的

在本文中我们将会讨论终止线程的规范用法 然后在一个例子中实际应用 在这个例子中我们模拟了文件拷贝和游戏绘图两种情形 做出的效果如下图所示 点击start后上方进度条会显示文件拷贝的进度 点击end则会停止拷贝 点击draw会在画面中不停绘制各种各样的矩形 点击stop则会停止绘制

首先我们来看两种情形的后台线程写法

public void run() {

try{

while(!Thread currentThread isInterrupted() more work to do)

{

do more work

}

}

catch(InterruptedException)

{

//thread was interrupted during sleep or wait

}

finally

{

cleanup if required

}

//exiting the run method terminates the thread }

public void run() {

try{

while( more work to do)

{

do more work

Thread sleep(delay)

}

}

catch(InterruptedException)

{

//thread was interrupted during sleep or wait

}

finally

{

cleanup if required

}

//exiting the run method terminates the thread }

第一种写法适用于后台下载 文件拷贝以及类似情形 第二种写法适合游戏画面刷新或者类似情形

第一种写法利用了interrupt方法 作为终止的请求 使得循环跳出 run方法执行完毕 而第二种方法则是利用当线程sleep的时候调用interrupt会抛出InterruptedException从而跳出了循环进而线程执行到结束

事实上这两种写法的区别就在于第二种使用了sleep

在我们的使用示例中 对应这两种方法的使用代码如下

这一段是实现文件拷贝的

private class CopyRunnable implements Runnable {

@Override

public void run() {

File fromFile = new File(Environment getExternalStorageDirectory()

getAbsolutePath() + /abc exe )

long fileLength = fromFile length()

long copyedLength = ;

File toFile = new File(Environment getExternalStorageDirectory()

getAbsolutePath() + /abc_ exe )

if (toFile exists()) {

toFile delete()

}

try {

FileInputStream fileInputStream = new FileInputStream(fromFile)

FileOutputStream fileOutputStream = new FileOutputStream(

toFile true)

byte[] buffer = new byte[ ];

int readLength = ;

while (!Thread currentThread() isInterrupted()

(readLength = fileInputStream read(buffer)) != ) {

fileOutputStream write(buffer buffer length)

copyedLength += readLength;

int progress = (int)

((float) copyedLength / fileLength * )

handler obtainMessage( progress ) sendToTarget()

}

} catch (FileNotFoundException e) {

e printStackTrace()

} catch (IOException e) {

e printStackTrace()

} finally {

handler obtainMessage( ) sendToTarget()

}

}

}

这一段是实现矩形绘图的

private class DrawRunnable implements Runnable {

@Override

public void run() {

try {

while (true) {

long beginTime = System currentTimeMillis()

paint setColor(getColor())

getCoor()

postInvalidate()

long endTime = System currentTimeMillis()

if (endTime beginTime ) {

Thread sleep( (endTime beginTime))

}

}

} catch (InterruptedException e) {

e printStackTrace()

} finally {

}

}

}

实际上这两种写法都是利用了interrupt方法的特点 通过线程的中断置位或者异常抛出来跳出循环进而终结线程 如果对这段代码感兴趣 可以到文章最后下载代码

最后做一下方法总结

void interrupt()

向线程发送中断请求 线程的中断状态将被设置为true 如果目前该线程被一个sleep调用阻塞 那么 InterruptedException异常被抛出

static boolean interrupted()

测试当前线程(即正在执行这一命令的线程)是否被中断 注意 这是一个静态方法 这一调用会产生副作用 它将当前线程的中断状态设置为false

boolean isInterrupted()

测试线程是否被中断 不像静态的中断方法 这一调用不会改变线程的中断状态

static Thread currentThread()

lishixinzhi/Article/program/Java/gj/201311/27558

北大青鸟java培训:线程的中断分为哪些情况?

相信大家在使用电脑的时候都有过这样的现象,就是在运行一个程序的时候,突然发现不需要了或者是需要启用其他软件的时候,我们会强制关闭这个软件的启动过程,成都java培训认为这个行为在java编程开发中就叫做线程的中断。

每一个线程都有一个boolean类型标志,用来表明当前线程是否请求中断,当一个线程调用interrupt()方法时,线程的中断标志将被设置为true。

我们可以通过调用Thread.currentThread().isInterrupted()或者Thread.interrupted()来检测线程的中断标志是否被置位。

这两个方法的区别是Thread.currentThread().isInterrupted()是线程对象的方法,调用它后不清除线程中断标志位;而Thread.interrupted()是一个静态方法,调用它会清除线程中断标志位。

一般来说中断线程分为三种情况:(一):中断非阻塞线程(二):中断阻塞线程(三):不可中断线程(一):中断非阻塞线程中断非阻塞线程通常有两种方式:(1)采用线程共享变量这种方式比较简单可行,需要注意的一点是共享变量必须设置为volatile,这样才能保证修改后其他线程立即可见。

(2)采用中断机制(二):中断阻塞线程当线程调用Thread.sleep()、Thread.join()、object.wait()再或者调用阻塞的i/o操作方法时,都会使得当前线程进入阻塞状态。

那么此时如果在线程处于阻塞状态是调用interrupt()方法设置线程中断标志位时会出现什么情况呢!此时处于阻塞状态的线程会抛出一个异常,并且会清除线程中断标志位(设置为false)。

这样一来线程就能退出阻塞状态。

当然抛出异常的方法就是造成线程处于阻塞状态的Thread.sleep()、Thread.join()、object.wait()这些方法。

需要注意的地方就是Thread.sleep()、Thread.join()、object.wait()这些方法,会检测线程中断标志位,如果发现中断标志位为true则抛出异常并且将中断标志位设置为false。

所以while循环之后每次调用阻塞方法后都要在捕获异常之后,调用Thread.currentThread().interrupt()重置状态标志位。

(三):不可中断线程有一种情况是线程不能被中断的,就是调用synchronized关键字和reentrantLock.lock()获取锁的过程。

但是如果调用带超时的tryLock方法reentrantLock.tryLock(longtimeout,TimeUnitunit),那么如果线程在等待时被中断,将抛出一个InterruptedException异常,这是一个非常有用的特性,因为它允许程序打破死锁。

你也可以调用reentrantLock.lockInterruptibly()方法,它就相当于一个超时设为无限的tryLock方法。

java线程的中断方法的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java线程的中断方法是什么、java线程的中断方法的信息别忘了在本站进行查找喔。