一 Two-Phase Termination Pattern

Two-Phase Termination Pattern,指的就是当希望结束一个线程的时候,送出一个终止请求,但是不会马上停止,做一些刷新工作。进入“终止处理中”,在该状态下,不会进行该线程日常工作任务的操作,而是进行一些终止操作。

这个方式所考虑的因素如下

1,必须要考虑到使得该线程能够安全的结束,Thread中的stop会有问题的,因为它会不管线程执行到哪里,都会马上停止,不能保证安全的结束。

2,一定能够进行正常的终止处理,在java中,这点可以使用finally来实现

3,能够高响应的终止,收到终止后,当线程在wait或者sleep或者join的时候,不用等到时间到才终止,而是马上中断线程的这些状态,进而进行终止操作。

当一个线程正在执行周期性的工作时候,在“作业中”发了停止执行绪的请求,此时该线程不能马上离开停止,而应该先做完本次周期内部的工作,然后进入“善后阶段”完成一些善后的工作,所谓的两阶段终止,即中止“运作阶段”,并完成“善后阶段”,完整的完成执行绪的工作。

两阶段终止线程的架构模式如下:

public class WorkerTerminalThread extends Thread {
// 已经送出终止请求为true,初始化的时候为false
//由于该字段可能会被多个线程访问修改,为了保护就使用这个
private volatile boolean shutdownRequested = false;
// 终止请求
public void shutdownRequest() {
shutdownRequested = true;
interrupt();
}
public boolean isShutdownRequest() {
return shutdownRequested;
}
// 具体动作
public final void run() {
try {
while (!shutdownRequested)
doWork();
} catch (InterruptedException e) {
}
// 终止处理中的工作,不会进行平常操作,但是会进行终止处理
finally {
doShutdown();
}
}
// 具体工作操作
private void doWork() throws InterruptedException {
}
// 终止后进行善后处理
private void doShutdown()
{
}
}

解释:

1,利用Volatile的原因是,这个字段可能会被多个线程所使用,进行修改,为了保护该字段,则可以利用同步方法或者同步代码块来保护,或者利用Volatile。用Volatile修饰的字段,强制了该成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。

2,这里运用了标识和中断状态来终止线程,之所以不单独用一个。原因是如果仅仅利用标识,无法是的那些处于wait、sleep或者join中的线程马上停止,响应性就会很差。加入了interrupt后,就可以立刻使得这些状态下的线程中断。如果仅仅利用interrupt,由于interrupt仅仅对于wait,sleep或join处进行抛出异常,如果工作代码执行在catch里,捕获了InterruptedException后,则此时interrupt就不起作用了。

转自:http://computerdragon.blog.51cto.com/6235984/1206548

例子:

为上面的2个方法添加如下:

private long counter = 0;

   //  作业
private void doWork() throws InterruptedException {
counter++;
System.out.println("doWork: counter = " + counter);
Thread.sleep(500);
} // 终止处理
private void doShutdown() {
System.out.println("doShutdown: counter = " + counter);
}
public class Test {
public static void main(String[] args) {
System.out.println("main: BEGIN");
try { TwoPhaseThread t = new TwoPhaseThread();
t.start(); Thread.sleep(10000); System.out.println("main: shutdownRequest");
t.shutdownRequest(); System.out.println("main: join"); t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("main: END");
}
}

输出:

main: BEGIN
doWork: counter = 1
doWork: counter = 2
doWork: counter = 3
doWork: counter = 4
doWork: counter = 5
doWork: counter = 6
doWork: counter = 7
doWork: counter = 8
doWork: counter = 9
doWork: counter = 10
doWork: counter = 11
doWork: counter = 12
doWork: counter = 13
doWork: counter = 14
doWork: counter = 15
doWork: counter = 16
doWork: counter = 17
doWork: counter = 18
doWork: counter = 19
doWork: counter = 20
main: shutdownRequest
main: join
doShutdown: counter = 20
main: END

评论:

Volatile这个修饰符在该例子中不可能被多个线程共享吧? 是不是需要在volatile前加static参数, 才可以算作是共享该变量呢? 谢谢~
[2楼]楼主      zhao_xiao_long 回复
2013-05-23 18:17:23
回复 liuyuanhui0301:[1楼]

线程是共享实例的所有的字段,不管是用什么修饰符的。这里加上这个关键之处就是,有可能会有多个线程对于该变量进行修改,当然这里也可以不加,因为修改这个变量的值只会是true而已,不影响.

 

多线程Two-Phase Termination Pattern两阶段终止模式的更多相关文章

  1. MySQL binlog 组提交与 XA(两阶段提交)

    1. XA-2PC (two phase commit, 两阶段提交 ) XA是由X/Open组织提出的分布式事务的规范(X代表transaction; A代表accordant?).XA规范主要定义 ...

  2. MySQL binlog 组提交与 XA(分布式事务、两阶段提交)【转】

    概念: XA(分布式事务)规范主要定义了(全局)事务管理器(TM: Transaction Manager)和(局部)资源管理器(RM: Resource Manager)之间的接口.XA为了实现分布 ...

  3. MySQL binlog 组提交与 XA(两阶段提交)--1

    参考了网上几篇比较靠谱的文章 http://www.linuxidc.com/Linux/2015-11/124942.htm http://blog.csdn.net/woqutechteam/ar ...

  4. 分布式事务、XA、两阶段提交、一阶段提交

    本文原文连接:http://blog.csdn.net/bluishglc/article/details/7612811 ,转载请注明出处! 1.XA XA是由X/Open组织提出的分布式事务的规范 ...

  5. XA: 事务和两阶段提交

    本文原文连接:http://blog.csdn.net/bluishglc/article/details/7612811 ,转载请注明出处! 1.XA XA是由X/Open组织提出的两阶段提交协议, ...

  6. 基于两阶段提交的分布式事务实现(UP-2PC)

    引言:分布式事务是分布式数据库的基础性功能,在2017年上海MySQL嘉年华(IMG)和中国数据库大会(DTCC2018)中作者都对银联UPSQL Proxy的分布式事务做了简要介绍,受限于交流形式难 ...

  7. OceanBase分布式事务以及两阶段提交实现具体设计

    眼下OceanBase中还存在updaeserver单点,下一步的开发任务是使得OB支持多点写入,支持多个UPS(及updateserver). 当中难点是怎样设计两阶段提交的失败恢复以及多机的快照读 ...

  8. mysql的两阶段协议(封锁定理,虫洞事务)

    我们都知道数据库的事务具有ACID的四个属性:原子性,一致性,隔离性和持久性.然后在多线程操作的情况下,如果不能保证事务的隔离性,就会造成数据的修改丢失(事务2覆盖了事务1的修改结果).读到脏数据(事 ...

  9. 分布式事务专题笔记(二)分布式事务解决方案之 2PC(两阶段提交)

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 前面已经了解了分布式事务的基础理论,以理论为基础,针对不同的分布式场景业界常见的解决方案有2PC.TCC ...

随机推荐

  1. 搜索-hdu-3720-Arranging Your Team

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3720 题目大意: 有23个人,告诉每个人的名字,能力值,以及踢球的位置.要求选出1个守门员,2个前锋 ...

  2. Linux驱动开发学习的一些必要步骤

      1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, ...

  3. migrate from weblogic to tomcat: directory mapping--reference

    Question: I am trying to migrate from weblogic to tomcat. in weblogic I have <virtual-directory-m ...

  4. java内存不足

    -Xmx1024m -Xms1024m -XX:PermSize=128m -XX:MaxPermSize=512m ------------------------- 亲测可用

  5. COGS 859. 数列

    /* 先来说一下第一眼看到想出的奇葩方法23333.. 找每个数左右有几个比他小的 前几天刚学了区间第k小的求法 然后... 枚举中间的那个点 对于左区间 二分找到他是第几大 右区间同理 然后 *起来 ...

  6. PID38 串的记数(codevs2077)

    /* 假设当前有a个A b个B c个C 用 f[a][b][c]来表示 那么如果这个串以A结尾 那就是 f[a-1][b][c]转移来的 所以构成 f[a][b][c]的串一定有一部分是 f[a-1] ...

  7. Wpf 数据绑定实例2

    1.简单DataContext绑定 //绑定对象 label.DataContext = Process.GetCurrentProcess(); Xaml代码: <Grid> <G ...

  8. asp.net中调用COM组件发布IIS时常见错误 80070005解决方案

    很多人在.net开发Web站点中引用了COM组件,调试时一切正常,但一发布到IIS下就提示如下错误: 检索 COM 类工厂中 CLSID 为 {} 的组件时失败,原因是出现以下错误: 80070005 ...

  9. android编译系统学习

    近日接手了后续android新平台项目搭建的任务. 本文内容基于sprd公司提供的android5.1源码. 一.一般的编译工作流程 我们代码一般情况下是从芯片商SPRD/MTK获得的. 源码的编译上 ...

  10. angularjs中ng-repeat-start与ng-repeat-end用法实例

    <!DOCTYPE html> <html lang="zh-CN" ng-app="app"> <head> <me ...