两阶段终止模式(Two-phase Termination)

1、核心思想
将停止线程这个动作分解为准备阶段和执行阶段,提供了一种通用的用于优雅地停止线程的方法
2、支持多个可停止线程需要共用一个线程停止标志场景,如多个线程实例使用一个队列中的数据。此时notifyThreadTermination发挥作用。

3、可复用代码Terminatable、AbstractTerminatableThread、TerminationToken

4、参考网站
WeakReference弱引用
学习地址:http://www.tuicool.com/articles/imyueq

5、剩余代码请参照 : http://blog.csdn.net/huzhiqiangcsdn/article/details/55045110


JAVA阻塞队列LinkedBlockingQueue 以及非阻塞队列ConcurrentLinkedQueue 的区别
学习地址:http://www.cnblogs.com/starcrm/p/4998067.html


public interface Terminatable {
public void terminate();
}

public class TerminationToken {
protected volatile boolean toShutDown = false;
public final AtomicInteger reservations = new AtomicInteger();

/**
* 在多个可停止线程实例共享一个TerminationToken实例的情况下,该队列用于记录那些共享TerminationToken实例
* 的可停止线程,以便尽可能减少锁的使用情况下,实现这些线程的停止
*/
private final Queue<WeakReference<Terminatable>> coordinatedThread;


public TerminationToken() {
coordinatedThread = new ConcurrentLinkedQueue<WeakReference<Terminatable>>();
}
public boolean isToShutDown() {
return toShutDown;
}

public void setToShutDown(boolean toShutDown) {
this.toShutDown = toShutDown;
}

protected void register(Terminatable thread){
coordinatedThread.add(new WeakReference<Terminatable>(thread));
}

/**
* 通知TerminationToken实例,共享该实例的所有可停止线程中的一个线程停止了,以便其停止其他为被停止的线程
* @param thread
* 已停止的线程
*/
protected void notifyThreadTermination(Terminatable thread){
WeakReference<Terminatable> wrThread;
Terminatable otherThread;

while(null != (wrThread=coordinatedThread.poll())){
otherThread = wrThread.get();
if(null != otherThread  && otherThread != thread){
otherThread.terminate();
}
}
}
}


public abstract class AbstractTerminatableThread extends Thread implements Terminatable {
public final TerminationToken terminationToken;
public AbstractTerminatableThread() {
this(new TerminationToken());
}


/**
* 线程间共享的线程终止标志实例
* @param terminationToken
*/
public AbstractTerminatableThread(TerminationToken terminationToken) {
this.terminationToken = terminationToken;
terminationToken.register(this);
}

/**
* 留给子类实现其线程处理逻辑
* @throws Exception
*/
protected abstract void doRun() throws Exception;


/**
* 留给子类实现,用于实现线程停止后的一些清理工作
*/
protected void doCleanup(Exception cause){
}

/**
* 留给子类实现,用于实现线程停止所需的操作
*/
protected void doTerminate(){
}

@Override
public void run() {
Exception ex = null;
try {
while(true){
//在执行线程的处理逻辑前先判断线程停止的标志
if(terminationToken.isToShutDown() && terminationToken.reservations.get()<=0){
break;
}
doRun();
}
} catch (Exception e) {
//使得线程能够响应interrupt调用而退出
ex = e;
}finally{
try {
doCleanup(ex);
} finally{
terminationToken.notifyThreadTermination(this);
}
}
}

@Override
public void interrupt() {
terminate();
}

@Override
public void terminate() {
terminationToken.setToShutDown(true);
try {
doTerminate();
} finally{
//若无待处理的任务,则试图强制终止线程
if(terminationToken.reservations.get()<=0){
super.interrupt();
}
}
}

public void terminate(boolean waitUtilThreadTerminated) {
terminate();
if(waitUtilThreadTerminated){
try {
this.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}

}


public class AlarmSendingThread extends AbstractTerminatableThread {
private final AlarmAgent alarmAgent = new AlarmAgent();
private final BlockingQueue<AlarmInfo> alarmQueue;
private final ConcurrentMap<String, AtomicInteger> submitedAlarmRegistry;


public AlarmSendingThread() {
super();
this.alarmQueue = new ArrayBlockingQueue<AlarmInfo>(30);
this.submitedAlarmRegistry = new ConcurrentHashMap<String, AtomicInteger>();
alarmAgent.init();
}

@Override
protected void doRun() throws Exception {
AlarmInfo alarm = alarmQueue.take();
terminationToken.reservations.decrementAndGet();
try {
alarmAgent.sendAlarm(alarm);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public int sendAlarm(final AlarmInfo alarmInfo){
if(terminationToken.isToShutDown()){
System.err.println("rejected alarm: " + alarmInfo.getId());
return -1;
}
try {
terminationToken.reservations.incrementAndGet();
alarmQueue.put(alarmInfo);
System.out.println("put queue alarm id=" + alarmInfo.getId());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return 0;
}

@Override
protected void doCleanup(Exception exp) {
if(null != exp && !(exp instanceof InterruptedException)){
exp.printStackTrace();
}
alarmAgent.disConnected();
}
}


public class AlarmMgr {
//单例模式,只在加载该类时new
private static final AlarmMgr instance = new AlarmMgr();
private volatile boolean shutDownRequested = false;
private final AlarmSendingThread alarmSendingThread;

private AlarmMgr(){
alarmSendingThread = new AlarmSendingThread();
}
public static AlarmMgr getInstance() {
return instance;
}

public int sengAlarm(String id, String type, String extraInfo){
System.out.println("trigger alarm " + type + ", " + id);
AlarmInfo alarmInfo = new AlarmInfo(id, type);
int duplicateCount = alarmSendingThread.sendAlarm(alarmInfo);
return duplicateCount;
}

public void init(){
alarmSendingThread.start();
}

public synchronized void shutdown() {
if(shutDownRequested){
throw new IllegalStateException("shutdown already requested!");
}
alarmSendingThread.terminate();
shutDownRequested = true;
}
}


public class Main {
public static void main(String[] args) {
AlarmMgr mgr = AlarmMgr.getInstance();

new Thread(){
public void run() {
for(int i=0; i<100;i++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mgr.sengAlarm(i+"", "", "");
}
};
}.start();

new Thread(){
public void run() {
mgr.init();
};
}.start();

new Thread(){
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mgr.shutdown();
};
}.start();
}
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值