Java没有提供不论什么机制来安全地(抢占式方法)终止线程,尽管Thread.stop和suspend等方法提供了这种机制,可是因为存在着一些严重的缺陷,因此应该避免使用。

但它提供了中断Interruption机制,这是一种协作机制,可以使一个线程终止还有一个线程的当前工作。


一、任务取消

取消操作的原因:

. 用户请求取消

. 有时间限制的操作

. 应用程序事件

. 错误

. 关闭

结束任务的四种方式:
1. run方法运行结束
2. 使用请求关闭标记(比如boolean开关)
3. 使用中断机制
4. 使用Future退出方法


2. 使用请求关闭标记
     当运行到并满足条件是使用return退出run方法
     变量须要volatile确保变量多线程环境下的可见性。

     -样例待填充,没有运行到推断条件就不会退出。所以不是马上退出的办法。

3. 使用中断机制
     长处是相对“请求关闭标记”对应更快一些。但也不是马上关闭线程。
     void        interrupt()       中断线程。

boolean   interrupted()   測试当前线程是否已经中断。

boolean   isInterrupted() 測试线程是否已经中断。

     InterruptedException异常

程序应该对线程中断作出恰当的响应。

//  1
Thread thread = new Thread("interrupt test") {
public void run() {
for (;;) {
doXXX();
if (Thread.interrupted()) {
break;
}
}
}
};
thread.start(); // 2
Thread thread = new Thread("interrupt test") {
public void run() {
for (;;) {
try {
doXXX();
} catch (InterruptedException e) {
break;
} catch (Exception e) {
// handle Exception
}
}
}
};
thread.start(); // 3
public void foo() throws InterruptedException {
if (Thread.interrupted()) {
throw new InterruptedException();
}
}


4. 使用Future退出方法

boolean cancel(boolean mayInterruptIfRunning)  

          试图取消对此任务的运行。 

boolean isCancelled()

          假设在任务正常完毕前将其取消,则返回 true。 


*. 处理不可中断的堵塞
*. 採用newTaskFor来封装费标准的取消


二、停止基于线程的服务

    之前的任务取消。主要是涉及怎样关闭单个线程而且都是由创建单个线程的对象来进行关闭操作,可是假设线程不是由对象自己而是由线程池统一创建的线程该怎样处理呢?
      1. 使用线程的对象进行关闭 - 当前即使不在对象中创建线程而由线程池创建,这个对象依旧能够关闭线程,这点一定要相信程序猿的破坏能力,仅仅是使用第2种方式更符合封装原则。

      2. 使用线程池统一管理 - 假设是使用ExecutorService创建就交由其进行关闭操作。

2. 使用线程池统一管理(关闭ExecutorService)
void shutdown()

     启动一次顺序关闭。运行曾经提交的任务,但不接受新任务。

假设已经关闭,则调用没有其它作用。

     -- 安全关闭方式。

List<Runnable> shutdownNow()

          试图停止全部正在运行的活动任务,暂停处理正在等待的任务。并返回等待运行的任务列表。 

          无法保证可以停止正在处理的活动运行任务。可是会尽力尝试。比如,通过 Thread.interrupt() 来取消典型的实现。所以不论什么任务无法响应中断都可能永远无法终止。 
          -- shutdownNow方法的局限性,强制关闭方式。
boolean isShutdown()

     boolean isShutdown()假设此运行程序已关闭。则返回 true。 

3. “毒丸”对象
仅仅有在生产者消费者的数量都已知的情况下,才干够使用“毒丸”对象。

三、处理非正常的线程终止
    Thread.UncaughtExceptionHandler全局的捕获的异常处理。通常在应用中用于异常的统计,收集到这些统计后能够相应用进行异常修复。


四、JVM关闭

1. 关闭钩子
Runtime.getRuntime().addShutdownHook(new Thread()) ;
void addShutdownHook(Thread hook) 

          注冊新的虚拟机来关闭钩子。


2. 守护线程
希望创建一个线程来运行一些辅助工作。但又不希望这个线程阻碍JVM的关闭。能够使用守护线程。


3. 终结器
避免使用终结器finalize





五、參考资料:

"程序应该对线程中断作出恰当的响应" 摘录自《温绍锦 - Java并发程序设计教程》



《Java并发编程实战》第七章 取消与关闭 读书笔记的更多相关文章

  1. Java并发编程实战---第六章:任务执行

    废话开篇 今天开始学习Java并发编程实战,很多大牛都推荐,所以为了能在并发编程的道路上留下点书本上的知识,所以也就有了这篇博文.今天主要学习的是任务执行章节,主要讲了任务执行定义.Executor. ...

  2. Java并发编程实战 第16章 Java内存模型

    什么是内存模型 JMM(Java内存模型)规定了JVM必须遵循一组最小保证,这组保证规定了对变量的写入操作在何时将对其他线程可见. JMM为程序中所有的操作定义了一个偏序关系,称为Happens-Be ...

  3. Java并发编程实战 第8章 线程池的使用

    合理的控制线程池的大小: 下面内容来自网络.不过跟作者说的一致.不想自己敲了.留个记录. 要想合理的配置线程池的大小,首先得分析任务的特性,可以从以下几个角度分析: 任务的性质:CPU密集型任务.IO ...

  4. 【java并发编程实战】第一章笔记

    1.线程安全的定义 当多个线程访问某个类时,不管允许环境采用何种调度方式或者这些线程如何交替执行,这个类都能表现出正确的行为 如果一个类既不包含任何域,也不包含任何对其他类中域的引用.则它一定是无状态 ...

  5. java并发编程实战《七》安全性、活跃性以及性能问题

    安全性.活跃性以及性能问题 安全性问题 那什么是线程安全呢?其实本质上就是正确性,而正确性的含义就是程序按照我们期望的执行,不要让我们感到意外. 存在共享数据并且该数据会发生变化,通俗地讲就是有多个线 ...

  6. Java并发编程实战 第6章 任务并行 第7章 取消与关闭

    ExecutorCompletionService CompletionService用来接收一个Executor的执行结果,将已经完成任务,放置在可使用 take 访问的队列上. 大概用法: Exe ...

  7. JAVA并发编程实战---第三章:对象的共享(2)

    线程封闭 如果仅仅在单线程内访问数据,就不需要同步,这种技术被称为线程封闭,它是实现线程安全性的最简单的方式之一.当某个对象封闭在一个线程中时,这种方法将自动实现线程安全性,即使被封闭的对象本生不是线 ...

  8. 《Java并发编程实战》第九章 图形用户界面应用程序界面 读书笔记

    一.为什么GUI是单线程化 传统的GUI应用程序通常都是单线程的. 1. 在代码的各个位置都须要调用poll方法来获得输入事件(这样的方式将给代码带来极大的混乱) 2. 通过一个"主事件循环 ...

  9. java并发编程实战:第二章----线程安全性

    一个对象是否需要是线程安全的取决于它是否被多个线程访问. 当多个线程访问同一个可变状态量时如果没有使用正确的同步规则,就有可能出错.解决办法: 不在线程之间共享该变量 将状态变量修改为不可变的 在访问 ...

随机推荐

  1. centOS设为文本启动方式

    centOS图形界面须要点用系统大量的内存和CPU资源,对于server而言,高效率是最重要的,因此将Centos 默认启动改为文本方式. 在终端中输入: vi /etc/inittab 有段说明文字 ...

  2. Swift - 系统声音服务的使用(播放声音,提醒,震动)

    1,系统声音服务介绍: 系统声音服务提供了一个Api,用于播放不超过30秒的声音.它支持的文件格式有限,具体的说只有CAF.AIF和使用PCM或IMA/ADPCM数据的WAV文件. 但此函数没有提供操 ...

  3. Servlet的学习之Session(3)

    在上一篇<Servlet的学习之Session(2)>我们知道了Session能实现一个会话过程中保存数据或者多个会话中实现同一个Session的关键因素就是Cookie,只是Cookie ...

  4. UVA - 12119 The Bells are Ringing (枚举)

    Perhaps you all have heard the mythical story about Tower of Hanoi (The details of this story is not ...

  5. 如何在使用摩托罗拉上的RSS阅读器应用进行一次订阅

    订阅一个CSDN的RSS为例. 1.打开RSS阅读器. 2.设置->新增订阅->手动新增 订阅URL:输入http://articles.csdn.net/api/rss.php?tid= ...

  6. Android应用中使用百度地图API并加入标注(一)

    网上一些资料这样的的内容已经过时了,这里是最新的内容,假设哪里不正确,请吐槽... 1)下载百度地图移动版API(Android)开发包       要在Android应用中使用百度地图API,就须要 ...

  7. Oracle SQL语句执行过程

    前言 QQ群讨论的时候有人遇到这样的问题:where子句中无法访问Oracle自定义的字段别名.这篇 博客就是就这一问题做一个探讨,并发散下思维,谈谈SQL语句的执行顺序问题. 问题呈现 直接给出SQ ...

  8. exception in thread main java.lang.NoClassDefFoundError wrong name解决方法

    当不含包层次的HelloWorld.java代码(此时程序运行正常) public class HelloWorld{ public static void main(String[] args)   ...

  9. [置顶] Vim用正则表达式进行批量修改

    vim可以设置 magic 这个东西, magic就是设置哪些元字符要加反斜杠哪些不用加的. 简单来说: magic(\m):除了 $ . * ^ 之外其他元字符都要加反斜杠. nomagic(\M) ...

  10. ThinkPhp学习01

    原文:ThinkPhp学习01 一.ThinkPHP的介绍           MVC  M - Model 模型                工作:负责数据的操作  V - View  视图(模板 ...