For investors
股价:
5.36 美元 %For investors
股价:
5.36 美元 %认真做教育 专心促就业
Java开发线程问题是学习编程开发技术需要掌握的重点知识之一,本文我们就一起来了解一下,关于线程的中断和终止有什么区别。
一、线程中断
线程中断仅仅是置线程的中断状态位,并不会停止线程(至于如何停止,本文后面会详述)。支持线程中断的方法(也就是线程中断后会抛出interruptedException的方法)就是在监视线程的中断状态,比如sleep、join等,一旦线程的中断状态被置为“中断状态”,就会抛出中断异常,并且将中断标志重新置为false。所以在Java中设置线程的中断状态位并不会产生对线程运行的实际影响,而是通过监视线程的状态位并做相应处理,或者通过抛出中断异常(InterruptedException)来通知用户进行处理。
和线程中断状态位有直接关系的方法主要有:interrupt()、interrupted()、isInterrupted(),其使用介绍如下:
1、interrupt()
interrupt()是Thread的实例方法,用于中断线程。调用该方法的线程的状态为将被置为"中断"状态。
2、interrupted()
interrupted()方法为Thread的静态方法,该方法就是直接调用当前线程的isInterrupted(true)的方法,是作用于当前线程,并且会重置当前线程的中断状态。
3、isInterrupted()
isInterrupted()方法是Thread的实例方法,是作用于调用该方法的线程对象所对应的线程,是直接调用对应线程的isInterrupted(false)的方法,不会重置对应线程的中断状态。
二、终止线程
当调用线程的start方法之后,线程会开始驱动任务,当任务执行完毕之后(也就是run方法执行结束)线程将终止,但是如果因为线程阻塞或者线程长时间执行而不能结束,所以我们希望能够通过某种途径可以终止线程以达到想要的效果,常用的方式有两种:中断、检查中断。
1、中断
Thread类包含interrupt()方法,因此你可以终止被阻塞的任务,这个方法将设置线程的中断状态。如果一个线程已经被阻塞,或者试图执行一个阻塞操作,那么设置这个线程的中断状态将导致线程抛出InterruptedException。当抛出该异常或者该任务调用Thread.interrupted()时,中断状态将被复位。
因为这种方式是在任务的run()方法中间打断,更像是抛出的异常,所以在Java线程的中断中用到了异常。而为了在以这种方式终止任务时,返回众所周知的良好状态,必须仔细考虑代码的执行路径,并仔细编写catch子句以正确清除所有事物。
如何调用interrupt?
为了调用interrupt(),你必须持有Thread对象。
如果你在Executor上调用shutdownNow(),那么它将发送一个interrupt()调用给它启动的所有线程。
如果希望只中断某个单一任务,那么可以通过调用submit()而不是executor()来启动任务,就可以持有该任务的上下文。submit()将返回一个泛型Future,持有这种Future的关键在于你可以在其上调用cancel(),并因此可以使用它来中断某个特定任务。如果你将true传递给cancel(),那么它就会拥有在该线程上调用interrupt()以停止这个线程的权限,因此,cancel()是一种中断由Executor启动的单个线程的方式。
对于互斥导致阻塞的中断:
在ReentrantLock上阻塞的任务具备可以被中断的能力(即interrupt()可以打断被ReentrantLock互斥所阻塞的调用),而在synchronized方法或临界区上阻塞的任务则不能被中断;
不能中断正在试图获取synchronized锁或者试图执行I/O操作的线程;
2、检查中断
当你在线程上调用interrupt()时,中断发生的时刻是在任务要进入到阻塞操作中,或者已经在阻塞操作内部时。但是如果根据程序运行的环境,你已经编写了可能会产生这种阻塞调用的代码,那又该怎么办呢?如果你只能通过在阻塞调用上抛出异常来退出,那么你就无法总是可以离开run()循环。因为如果你调用interrupt()以停止某个任务,那么在run循环碰巧没有产生任何阻塞调用的情况下这种方式就不起作用了,需要另一种方式来退出。Thread.interrupted()提供了离开run()循环而不抛出异常的二种方式。
这种机会是由中断状态来表示的,其状态可以通过调用interrupt()来设置。你可以通过调用interrupted()来检查中断状态,这不仅可以告诉你interrupt()是否被调用过,而且还可以清除中断状态。清除中断状态可以确保并发结构不会就某个任务被中断这个问题通知你两次,你可以经由单一的InterruptedException或单一的成功的Thread.interrupted()测试来得到这种通知。如果想要再次检查以了解是否被中断,则可以在调用Thread.interrupted()时将结果存储起来。
以上就是本文为大家分享的关于Java开发线程的中断和终止有什么区别的文章,希望对大家有所帮助。