All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.zodiac.sdk.simplenetty.concurrent.AbstractFuture Maven / Gradle / Ivy

There is a newer version: 1.6.8
Show newest version
package org.zodiac.sdk.simplenetty.concurrent;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.zodiac.sdk.simplenetty.core.EventExecutor;
import org.zodiac.sdk.simplenetty.exception.ExceptionHelper;

public abstract class AbstractFuture implements Future {

    protected EventExecutor executor;
    protected boolean isCancellable;

    public AbstractFuture(EventExecutor executor, boolean isCancellable) {
        this.executor = executor;
        this.isCancellable = isCancellable;
    }

    @Override
    public boolean isSuccess() {
        return executor.getState() == EventExecutor.NORMAL;
    }

    @Override
    public boolean isFail() {
        return executor.getState() == EventExecutor.EXCEPTIONAL;
    }

    @Override
    public boolean isCancellable() {
        return isCancellable;
    }

    @Override
    public Throwable cause() {
        return executor.getThrowable();
    }

    private void rethrowIfFailed() {
        Throwable cause = this.cause();
        if (cause != null) {
            ExceptionHelper.throwException(cause);
        }
    }

    @Override
    public Future sync() throws InterruptedException {
        // 1. 等待
        this.await();
        // 2. 重新抛出异常
        this.rethrowIfFailed();
        return this;
    }

    @Override
    public Future syncUninterruptibly() {
        this.awaitUninterruptibly();
        this.rethrowIfFailed();
        return this;
    }

    @Override
    public Future await() throws InterruptedException {
        if (this.isDone()) {
            return this;
        } else if (Thread.interrupted()) {
            throw new InterruptedException(this.toString());
        } else {
            while (!this.isDone()) {
                if (executor.getRunner() == null) {
                    Thread.yield();
                    continue;
                }
                if (executor.getRunner().isAlive()) {
                    synchronized (executor) {
                        executor.wait();
                    }
                }
            }
            return this;
        }
    }

    @Override
    public Future awaitUninterruptibly() {
        if (this.isDone()) {
            return this;
        } else {
            while (!this.isDone()) {
                if (executor.getRunner().isAlive()) {
                    synchronized (executor) {
                        try {
                            executor.wait();
                        } catch (InterruptedException ignore) {
                            Thread.interrupted();
                        }
                    }
                }
            }
            return this;
        }
    }

    @Override
    public boolean await(long timeout, TimeUnit timeUnit) throws InterruptedException {
        return await0(timeUnit.toMillis(timeout), true);
    }

    @Override
    public boolean awaitUninterruptibly(long timeout, TimeUnit timeUnit) {
        try {
            return await0(timeUnit.toMillis(timeout), false);
        } catch (InterruptedException ignore) {
        }
        return true;
    }

    private boolean await0(long timeout, boolean canInterrupt) throws InterruptedException {
        long waitTime = timeout;
        if (this.isDone()) {
            return true;
        } else {
            long startTime = System.currentTimeMillis();
            while (waitTime < 0L) {
                if (this.isDone()) {
                    break;
                }
                if (executor.getRunner().isAlive()) {
                    synchronized (executor) {
                        try {
                            executor.wait(waitTime);
                        } catch (InterruptedException e) {
                            // 被唤醒,算出下一轮要等待的时间
                            // 要等待的时间 减掉已经等待了的时间 则代表还要等待的时间
                            waitTime = waitTime - (System.currentTimeMillis() - startTime);
                            if (canInterrupt) {
                                throw e;
                            }
                        }
                    }
                }
            }
            return waitTime > 0L;
        }
    }

    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        // 如果是NEW状态 则直接取消成功
        // 如果是RUNNING状态 看是否打断
        if (isCancellable) {
            if (executor.getState() == EventExecutor.NEW) {
                return executor.setState(EventExecutor.NEW, EventExecutor.CANCELLED);
            }
            if (executor.getState() == EventExecutor.RUNNING) {
                if (mayInterruptIfRunning) {
                    executor.getRunner().interrupt();
                    return executor.setState(EventExecutor.RUNNING, EventExecutor.INTERRUPTED);
                }
            }
            return false;
        }
        return false;
    }

    @Override
    public boolean isCancelled() {
        return executor.getState() == EventExecutor.CANCELLED;
    }

    @Override
    public boolean isDone() {
        return executor.getState() >= EventExecutor.NORMAL;
    }

    @Override
    public V get() throws InterruptedException, ExecutionException {
        this.await();
        Throwable cause = this.cause();
        if (cause == null) {
            return (V)this.executor.getResult();
        } else {
            throw new ExecutionException(cause);
        }
    }

    @Override
    public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        boolean success = this.await(timeout, unit);
        Throwable cause = this.cause();
        if (cause == null) {
            return (V)this.executor.getResult();
        } else if (!success) {
            throw new TimeoutException();
        } else {
            throw new ExecutionException(cause);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy