我通过创建一个扩展基本Runnable
接口以提供更健壮的线程架构的框架来完成类似的事情。后来我发现它与 GWT 中用于类似目的的异步代码惊人地相似。
这是凭记忆,但基本上可以归结为:
public interface AsyncRunnable<T> extends Runnable
{
AsyncCallback<T> getCallback();
T runAsync();
}
public interface AsyncCallback<T>
{
void onSuccess(T data);
void onFailure(Exception exception);
}
public interface AsyncCallbackInvoker<T> extends Runnable
{
// implies requirement for callback...
AsyncCallback<T> getCallback();
}
public class SuccessfulAsyncCallbackInvoker<T> implements AsyncCallback<T>
{
private final AsyncCallback<T> callback;
private final T data;
public SuccessfulAsyncCallbackInvoker(AsyncCallback<T> callback, T data)
{
// note: data being null may be valid; callback would not be
this.callback = callback;
this.data = data;
}
@Override
public void run()
{
callback.onSuccess(data);
}
@Override
public AsyncCallback<T> getCallback()
{
return callback;
}
}
public class FailureAsyncCallbackInvoker<T> implements AsyncCallback<T>
{
private final AsyncCallback<T> callback;
private final Exception exception;
public FailureAsyncCallbackInvoker(AsyncCallback<T> callback, Exception exception)
{
// note: data being null may be valid; callback would not be
this.callback = callback;
this.exception= exception;
}
@Override
public void run()
{
callback.onFailure(exception);
}
@Override
public AsyncCallback<T> getCallback()
{
return callback;
}
}
public abstract class AbstractAsyncRunnable<T> implements AsyncRunnable<T>
{
private final AsyncCallback<T> callback;
public AbstractAsyncRunnable(AsyncCallback<T> callback)
{
// if == null -> throw
this.callback = callback;
}
@Override
public /* final */ void run()
{
AsyncCallbackInvoker<T> invoker;
try
{
T data = runAsync();
invoker = new SuccessfulAsyncCallbackInvoker<T>(callback, data);
}
catch (Exception e)
{
invoker = new FailureAsyncCallbackInvoker<T>(callback, e);
}
invokeCallback(invoker);
}
// allows overriding to put callback on whatever Thread you want
protected void invokeCallback(AsyncCallbackInvoker<T> invoker)
{
invoker.run();
}
}
在实践中,它已被证明非常健壮,特别是通过提供覆盖能力,invokeCallback
我们能够利用许多线程安全操作来保证响应。
在实践中,实现只需要重写runAsync
方法AsyncRunnable
并提供AsyncCallback
他们认为合适的任何东西。重要的是要注意,在某些情况下,您确实将它用于简单地标记完成,并且在这种情况下可以T
(Void
如果您使用它)。return null
runAsync