ITPub博客

首页 > Linux操作系统 > Linux操作系统 > AsyncToken

AsyncToken

原创 Linux操作系统 作者:chenlm20042004 时间:2011-06-01 21:33:15 0 删除 编辑

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

package cn.org.rapid_framework.util.concurrent.async; 

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

import javax.swing.SwingUtilities;

/**
*

* 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;
* }
*

* @see AsyncTokenTemplate
* @author badqiu
*/

public class AsyncToken {
public static final String DEFAULT_TOKEN_GROUP = "default";
private static AtomicLong tokenIdSequence = new AtomicLong(1);

//tokenGroup tokenName tokenId
private String tokenGroup = DEFAULT_TOKEN_GROUP;
private String tokenName;
private long tokenId;

private List _responders = new ArrayList(2);

private UncaughtExceptionHandler uncaughtExceptionHandler;
private T _result;
private Exception _fault;
private boolean _isFiredResult;

private CountDownLatch awaitResultSignal = null;

public AsyncToken(){
this(null);
}

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

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

public String getTokenGroup() {
return tokenGroup;
}

public void setTokenGroup(String tokenGroup) {
if(tokenGroup == null) throw new IllegalArgumentException("'tokenGroup' must be not null");
this.tokenGroup = tokenGroup;
}

public String getTokenName() {
return tokenName;
}

public void setTokenName(String tokenName) {
this.tokenName = tokenName;
}

public long getTokenId() {
return tokenId;
}

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

public void addResponder(final IResponder responder) {
addResponder(responder,false);
}
/**
*/

public void addResponder(final IResponder responder,boolean invokeResponderInOtherThread) {
_responders.add(responder);

if(_isFiredResult) {
if(invokeResponderInOtherThread) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
fireResult2Responder(responder);
}
});
}else {
fireResult2Responder(responder);
}
}
}

public List getResponders() {
return _responders;
}

public boolean hasResponder() {
return _responders != null && _responders.size() > 0;
}

public UncaughtExceptionHandler getUncaughtExceptionHandler() {
return uncaughtExceptionHandler;
}

public void setUncaughtExceptionHandler(UncaughtExceptionHandler uncaughtExceptionHandler) {
this.uncaughtExceptionHandler = uncaughtExceptionHandler;
}

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

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

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

public void setComplete(){
setComplete(null);
}

public void setComplete(T result) {
if(_isFiredResult) throw new IllegalStateException("token already fired");
this._result = result;
fireResult2Responders();
}

public void setFault(Exception fault) {
if(fault == null) throw new NullPointerException();
if(_isFiredResult) throw new IllegalStateException("token already fired");
this._fault = fault;
fireResult2Responders();
}

public boolean isDone() {
synchronized (this) {
return _isFiredResult;
}
}

/**
* @see Future
*/

public Object waitForResult() throws InterruptedException,Exception {
return waitForResult(-1, null);
}
/**
* @see Future
*/

public Object waitForResult(long timeout,TimeUnit timeUnit) throws InterruptedException,Exception {
synchronized(this) {
if(_isFiredResult) {
if(_fault != null) {
throw _fault;
}else {
return _result;
}
}

awaitResultSignal = new CountDownLatch(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后再添加监听方法

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15874680/viewspace-696911/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-09-17

  • 博文量
    20
  • 访问量
    29323