非同期でやりとりを行うための 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();
            }
        }
    }
}