将停止线程这个动作分解为准备阶段和执行阶段,提供了一种通用的用于优雅地停止线程的方法
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();
}
}