非同期でやりとりを行うための Future クラスを作ってみた
インターフェースは C++0x で追加されるものを参考にして、実装は Future パターンまんまです。
public final class FutureException extends Exception { private Exception inner; FutureException(Exception inner) { this.inner = inner; } FutureException(Exception inner, String arg) { super(arg); this.inner = inner; } public Exception getInnerException() { return inner; } }
public final class Promise { Object value; FutureException exception; int readyState; public Future getFuture() { return new Future(this); } public void setValue(Object r) { synchronized (this) { if (readyState != 0) throw new IllegalArgumentException(); value = r; readyState = 1; this.notifyAll(); } } public void setException(Exception e) { synchronized (this) { if (readyState != 0) throw new IllegalArgumentException(); exception = new FutureException(e); readyState = 2; this.notifyAll(); } } }
public final class Future { private Promise promise; Future(Promise promise) { this.promise = promise; } public Object get() throws InterruptedException, FutureException { synchronized(promise) { while (!isReady()) { promise.wait(); } if (hasException()) { throw promise.exception; } else { return promise.value; } } } public boolean isReady() { synchronized (promise) { return promise.readyState != 0; } } public boolean hasValue() { synchronized (promise) { return promise.readyState == 1; } } public boolean hasException() { synchronized (promise) { return promise.readyState == 2; } } public void waitResult() throws InterruptedException { synchronized(promise) { while (!isReady()) { promise.wait(); } } } }