博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《Java并发编程实战》(六)---- 取消与关闭
阅读量:5140 次
发布时间:2019-06-13

本文共 2005 字,大约阅读时间需要 6 分钟。

  任务和线程的启动很容易。然而,有时候我们希望提前结束任务或线程,或许是因为用户取消了操作,或者应用程序需要被快速关闭。

  要使任务和线程能安全/快速/可靠地停止下来,并不是一件容易的事。Java没有提供任何机制来安全地终止线程,但它提供了中断,这是一种协作机制,能够使一个线程终止另一个线程的工作。

  1,任务取消

  如果外部代码能在某个操作正常完成之前将其置入“完成”状态,那么这个操作就可以称为可取消的。

协作机制能设置某个标志位,任务会定期查看这个标志,如果设置了标志,那么任务将提前结束。

2,线程中断

线程中断是一种协作机制,线程可以通过这种机制来通知另一个线程,告诉它在合适的活着可能的情况下停止当前工作,并转而执行其他的工作。

每个线程都有一个boolean类型的中断状态。当中断线程时,这个线程的中断状态将被设置为true。在Thread中包涵了中断线程以及查询线程中断状态的方法。interrupt方法能中断目标线程,而isInterrupted方法能返回目标线程的中断状态,静态的interrupted方法将清除当前的中断状态,并返回它之前的值。

阻塞库方法,例如Thread.sleep()、Object.wait()、Therad.join()等,都会去检查线程何时中断,并且在发现中断时提前返回。他们在响应中断时执行的操作包括: 清除中断状态、抛出InterruptedException,表示阻塞操作由于中断而提前结束。

调用interrupt并不意味着立即停止目标线程正在进行的工作,而只是传递了请求中断的消息。然后由线程在下一个合适的时刻中断自己。

3,通过Future.cancel()来实现取消

public static void timeRun(Runnable r, long timeout, TimeUnit unit) throws InterruptedException {    Future
task = taskExec.submit(t); try { task.get(timeout, unit); } catch (TimeoutException e) { } catch (ExecutionException e) { throw launderThrowable(e.getCause()); } finally { task.cancel(true); }}

当Future抛出InterruptedException或TimeoutException时,如果知道不再需要结果,那么就可以调用Future.cancel来取消任务 。

 

,4,处理不可中断的阻塞

并非所有的可阻塞方法或者阻塞机制都能响应中断;如果一个线程由于执行IO或者等待获得内置锁而阻塞,那么请求只能设置线程的中断状态,除此之外没有任何其他作用。对于那些执行不可中断操作而被阻塞的线程,可以使用类似于中断的手段来停止这些线程,但这要求我们必须知道线程阻塞的原因 。

Java.io包中的同步Socket I/O: 虽然InputStream和OutputStream中的read和write不会响应中断,但通过关闭底层的套接字,可以使得由于执行read或write方法而阻塞的线程抛出一个SocketException。

获取某个锁:如果一个线程由于等待某个内置锁而阻塞,那么将无法响应中断,因为线程认为它肯定会获得锁,所以不会理会中断请求。但是Lock类中提供了lockInterruptibly方法,该方法允许在等待一个锁的同事仍能响应中断。

所以知道了线程阻塞的原因,还是可以通过捕获异常或者调用自定义中断方法来进行取消操作。

5,采用newTaskFor来封装非标准的取消

newTaskFor是Java 6在ThreadPoolExecutor中的新增功能。当把一个Callable提交给ExecutorService时,submit方法会返回一个Future,可以通过这个Future来取消任务。newTaskFor是一个工厂方法,它将创建Future来代表任务,newTaskFor还能返回一个RunnableFuture接口,该接口扩展了Future和Runnable,并由FutureTask实现。

 

6,处理非正常的线程终止

导致线程提前死亡的最主要原因是RuntimeException。由于这些异常表示出现了某种编程错误或者其他不可修复的错误,因此它们通常不会被捕获。它们不会在调用栈中逐层传递,而是默认地在控制台输出栈追踪消息,并终止线程。

 

转载于:https://www.cnblogs.com/IvySue/p/6955260.html

你可能感兴趣的文章
Hadoop Distributed File System 简介
查看>>
文档通信(跨域-不跨域)、时时通信(websocket)、离线存储(applicationCache)、开启多线程(web worker)...
查看>>
常用正则表达式
查看>>
队列的基本使用方法
查看>>
解题:USACO18FEB Taming the Herd
查看>>
ACM-括号匹配问题
查看>>
使用Python中的urlparse、urllib抓取和解析网页(一)(转)
查看>>
Linux_屏蔽360、scanv、QQ管家等IP扫描
查看>>
LeetCode 538. Convert BST to Greater Tree
查看>>
@JoinColumn
查看>>
2019浙师大校赛(浙大命题)(upc复现赛)总结
查看>>
Git多人协作常用命令
查看>>
connectionString属性server、database设置
查看>>
php下载图片
查看>>
C算法编程题(五)“E”的变换
查看>>
深入理解Web Server原理----在CC3200 WiFi模块上构建轻量级Web Server
查看>>
ecshop如何让所有页面都显视最能文章以提高SEO优化效果
查看>>
Android 6.0 使用 Apache HttpClient
查看>>
SQL server 的约束条件【转】
查看>>
iOS 弹出键盘,输入框上移问题
查看>>