В чем разница между двумя вариантами использования FutureTask? - PullRequest
0 голосов
/ 29 октября 2019

использовать пул потоков:

ExecutorService exec = Executors.newFixedThreadPool(5);
FutureTask<Integer> ft = new FutureTask<Integer>(() -> rpcMethod());
exec.submit(ft);

вызов метода запуска:

FutureTask<Integer> ft = new FutureTask<Integer>(() -> rpcMethod());
ft.run()

Я посмотрел исходный код метода запуска, как будто это был синхронный вызов, кажется, чтонет новой темы. Причина, по которой у меня возникла эта проблема, заключается в том, что я посмотрел на исходный код RpcContext # asyncCall Даббо и обнаружил, что он напрямую использует FutureTask # run. Вот некоторая часть кода.

public <T> Future<T> asyncCall(Callable<T> callable) {
        try {
            try {
                setAttachment(Constants.ASYNC_KEY, Boolean.TRUE.toString());
                final T o = callable.call();
                //local调用会直接返回结果.
                if (o != null) {
                    FutureTask<T> f = new FutureTask<T>(new Callable<T>() {
                        public T call() throws Exception {
                            return o;
                        }
                    });
                    f.run();
                    return f;
                } else {

                }

1 Ответ

1 голос
/ 29 октября 2019

FutureTask является реализацией Runnable.

разница составляет

, если вы используете exec.submit (ft) ;его асинхронность выполняется в двух разных потоках.

, если вы используете ft.run () ;он был выполнен в том же потоке.

Если есть какие-либо сомнения, попробуйте это. Я поместил getResult () в другой метод, чтобы у вас был более явный стек вызовов:

public class FutureExample {

private Callable<Long> call = new Callable<Long>() {

    private Long getResult(){
        return Thread.currentThread().getId();
    }

    @Override
    public Long call() {
        return getResult();
    }
};

private Long callByRun() throws ExecutionException, InterruptedException {
    FutureTask<Long> ft = new FutureTask<>(call);
    ft.run();
    return ft.get();
}

private Long callByExec() throws ExecutionException, InterruptedException {
    ExecutorService pool = Executors.newFixedThreadPool(5);
    FutureTask<Long> ft = new FutureTask<>(call);
    pool.submit(ft);
    Long result = ft.get();
    pool.shutdown();
    return result;
}

public static void main(String[] args) throws ExecutionException, InterruptedException {
    Long mainThreadId = Thread.currentThread().getId();
    System.out.println(String.format("main: %d callByRun %d", mainThreadId, new FutureExample().callByRun()));
    System.out.println(String.format("main: %d callByExec %d", mainThreadId, new FutureExample().callByExec()));
}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...