异步令牌AsyncToken

AsyncToken模式,替换通常的Listener模式

packagecn.org.rapid_framework.util.concurrent.async;

importjava.util.ArrayList;
importjava.util.List;
importjava.util.concurrent.Callable;
importjava.util.concurrent.CountDownLatch;
importjava.util.concurrent.Future;
importjava.util.concurrent.TimeUnit;
importjava.util.concurrent.atomic.AtomicLong;

importjavax.swing.SwingUtilities;

/**
* <pre>
* public void testSendEmail() {
* final String address = "badqiu(a)gmail.com";
* final String subject = "test";
* final String content = "async token test";
* AsyncToken token = sendAsyncEmail(address,subject,content);
*
* token.addResponder(new IResponder() {
* public void onFault(Exception fault) {
* System.out.println("email send fail,cause:"+fault);
* sendAsyncEmail(address,subject,content);
* }
* public void onResult(Object result) {
* System.out.println("email send success,result:"+result);
* }
* });
* }
*
* public AsyncToken sendAsyncEmail(String address,String subject,String content) {
* final AsyncToken token = new AsyncToken();
*
* Thread thread = new Thread(new Runnable() {
* public void run() {
* try {
* //do send email job...
* token.setComplete(executeResult);
* }catch(Exception e) {
* token.setFault(e);
* }
* }
* });
* thread.start();
*
* return token;
* }
* </pre>
* @see AsyncTokenTemplate
* @author badqiu
*/

publicclassAsyncToken<T> {
publicstaticfinalString DEFAULT_TOKEN_GROUP = "default";
privatestaticAtomicLong tokenIdSequence =newAtomicLong(1);

//tokenGroup tokenName tokenId
privateString tokenGroup = DEFAULT_TOKEN_GROUP;
privateString tokenName;
privatelongtokenId;

privateList<IResponder> _responders =newArrayList(2);

privateUncaughtExceptionHandler uncaughtExceptionHandler;
privateT _result;
privateException _fault;
privateboolean_isFiredResult;

privateCountDownLatch awaitResultSignal =null;

publicAsyncToken(){
this(null);
}

publicAsyncToken(UncaughtExceptionHandler uncaughtExceptionHandler) {
this(DEFAULT_TOKEN_GROUP,null);
this.uncaughtExceptionHandler = uncaughtExceptionHandler;
}

publicAsyncToken(String tokenGroup,String tokenName) {
setTokenGroup(tokenGroup);
setTokenName(tokenName);
this.tokenId = tokenIdSequence.getAndIncrement();
}

publicString getTokenGroup() {
returntokenGroup;
}

publicvoidsetTokenGroup(String tokenGroup) {
if(tokenGroup ==null)thrownewIllegalArgumentException("'tokenGroup' must be not null");
this.tokenGroup = tokenGroup;
}

publicString getTokenName() {
returntokenName;
}

publicvoidsetTokenName(String tokenName) {
this.tokenName = tokenName;
}

publiclonggetTokenId() {
returntokenId;
}

/**
* addResponder(responder,false);
* @param responder
*/

publicvoidaddResponder(finalIResponder<T> responder) {
addResponder(responder,false);
}
/**
*/

publicvoidaddResponder(finalIResponder<T> responder,booleaninvokeResponderInOtherThread) {
_responders.add(responder);

if(_isFiredResult) {
if(invokeResponderInOtherThread) {
SwingUtilities.invokeLater(newRunnable() {
publicvoidrun() {
fireResult2Responder(responder);
}
});
}else{
fireResult2Responder(responder);
}
}
}

publicList<IResponder> getResponders() {
return_responders;
}

publicbooleanhasResponder() {
return_responders !=null&& _responders.size() > 0;
}

publicUncaughtExceptionHandler getUncaughtExceptionHandler() {
returnuncaughtExceptionHandler;
}

publicvoidsetUncaughtExceptionHandler(UncaughtExceptionHandler uncaughtExceptionHandler) {
this.uncaughtExceptionHandler = uncaughtExceptionHandler;
}

privatevoidfireResult2Responder(IResponder responder) {
try{
if(_fault !=null) {
responder.onFault(_fault);
}else{
responder.onResult(_result);
}
}catch(RuntimeException e) {
if(getUncaughtExceptionHandler() !=null) {
getUncaughtExceptionHandler().uncaughtException(responder, e);
}else{
throwe;
}
}catch(Error e) {
if(getUncaughtExceptionHandler() !=null) {
getUncaughtExceptionHandler().uncaughtException(responder, e);
}else{
throwe;
}
}
}

privatevoidfireResult2Responders() {
synchronized(this) {
_isFiredResult =true;
if(awaitResultSignal !=null) {
awaitResultSignal.countDown();
}
}

for(IResponder r : _responders) {
fireResult2Responder(r);
}
}

publicvoidsetComplete(){
setComplete(null);
}

publicvoidsetComplete(T result) {
if(_isFiredResult)thrownewIllegalStateException("token already fired");
this._result = result;
fireResult2Responders();
}

publicvoidsetFault(Exception fault) {
if(fault ==null)thrownewNullPointerException();
if(_isFiredResult)thrownewIllegalStateException("token already fired");
this._fault = fault;
fireResult2Responders();
}

publicbooleanisDone() {
synchronized(this) {
return_isFiredResult;
}
}

/**
* @see Future
*/

publicObject waitForResult()throwsInterruptedException,Exception {
returnwaitForResult(-1,null);
}
/**
* @see Future
*/

publicObject waitForResult(longtimeout,TimeUnit timeUnit)throwsInterruptedException,Exception {
synchronized(this) {
if(_isFiredResult) {
if(_fault !=null) {
throw_fault;
}else{
return_result;
}
}

awaitResultSignal =newCountDownLatch(1);
}

if(timeout > 0) {
awaitResultSignal.await(timeout,timeUnit);
}else{
awaitResultSignal.await();
}

if(_fault !=null) {
throw_fault;
}else{
return_result;
}
}

}

文章总结了AsyncTokenVS Observer好处和异同

使用AsyncToken的好处:

1. token可以无限传递,只要对方法的执行结果感兴趣,都可以监听方法的执行结果.

2. 拥有上下文,还可以引用前面的参数,以执行任务email重发这种任务

3. 一个token与一个方法对应,方法调用时你即知道token对应的事件,不需要使用listener模式中的一般用EventType来区别不现的事件

3. 灵活转换,也可以将上面的token再转至listener,再由listener以事件的方式派发事件

与Listener的异同:

1.token可以无限传递

2.没有使用事件或是监听不同的方法,listener一般配合需要使用事件,然后由事件进行参数的绑定.

3.listener模式一般是先设置好listener,而AsyncToken可以得到token后再添加监听方法


 

你可能感兴趣的:(职场,异步,休闲,asynctoken)