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. [置顶] gis海量资源网盘提供VIP账号无广告高速下载 (更新更多资源)

    资源网盘下载地址:http://laoheitan.bego.cc/ 城通网盘 vip帐号共享 省去 烦人的 广告  多任务同时下载 独乐乐 不如众乐乐 好人 勿改密码. 获取到 vip下载连接后 请 ...

  2. Swift - 使用UIImagePickerController从相册选择照片并展示

    1,UIImagePickerController介绍 (1)选择相册中的图片或者拍照,都是通过UIImagePickerController控制器实例化一个对象,然后通过self.presentVi ...

  3. webdynpro 组件重用 传值问题

    组件zwd1,需要调用组件zwd2的时候,zwd2组件控制器中需要定义一个方法,定义所要传输的参数,并且该方法需要定义为interface方法. 组件zwd1可以通过代码向导调用组件zwd2,的该方法 ...

  4. JVM内存管理 (转)

    一.物理内存与虚拟内存1.物理内存                (1)RAM        所谓物理内存就是我们通常所说的RAM(随机存储器).        (2)寄存器        在计算机中 ...

  5. 【Demo 0003】Android 事件

    本章学习要点:        1.  了解Android中资源用途:        2.  掌握资源使用通用规则:        3.  掌握具体资源使用方法;

  6. 8086 CPU 寻址方式

    8086 CPU 寻址方式灵活.有以下几种 idata 表示常量 1.   [ idata ] 用一个常量来表示地址,可用于直接定位内存单元,但是在 MASM中要显实在的说明 ds 段寄存器, 比如 ...

  7. Makefile条件推断 ——————————【Badboy】

    使用条件推断,能够让make依据执行时的不同情况选择不同的执行分支. 条件表达式能够是比較变量的值,或是比較变量和常量的值. 一.演示样例 以下的样例,推断$(CC)变量是否"gcc&quo ...

  8. android json 解析 简单示例

    1 下面是一个简单的json 解析的demo,废话不多说,直接上代码 package com.sky.gallery; import java.io.ByteArrayOutputStream; im ...

  9. osgEarth开发之OSG解构——失败的尝试

    概述 本文在吸收了<最长的一帧>以及相关参考资料的基础之上解读OSG的基础数据结构,渲染方法. 实现 在这第一部分里,要理解的是run函数的实现,因为以下这一段证明了它的重要性和强大的能力 ...

  10. MingW环境下的windows编程

    一般在进行windows编程时都使用vc++精简版,其插入菜单,图片等资源等更简单,且vc中对中文有更好的支持,win7下安装的Mingw中文并不能很好地显示,有光标显示的位置和光标实际位置不符的问题 ...