Як створити завершене майбутнє в Java


87

Який найкращий спосіб побудувати завершене майбутнє в Java? Я застосував своє власне CompletedFutureнижче, але сподівався на щось подібне, яке вже існує.

public class CompletedFuture<T> implements Future<T> {
    private final T result;

    public CompletedFuture(final T result) {
        this.result = result;
    }

    @Override
    public boolean cancel(final boolean b) {
        return false;
    }

    @Override
    public boolean isCancelled() {
        return false;
    }

    @Override
    public boolean isDone() {
        return true;
    }

    @Override
    public T get() throws InterruptedException, ExecutionException {
        return this.result;
    }

    @Override
    public T get(final long l, final TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
        return get();
    }
}

1
Найкращий спосіб - не створювати його! ;-) Чому потрібно реалізовувати Майбутнє? Ви не можете замість цього використовувати існуючі об'єкти, які повертають майбутнє?
assylias

1
Я підозрюю, що жоден не існує, бо я ніколи не бачив причини, щоб його мати. Можливо, ви могли б пояснити, що ви намагаєтесь зробити?
Пітер Лорі

1
@PeterLawrey Я припускаю, що він потрібен для якогось API, який з якихось перекручених причин хоче працювати з ф'ючерсами, хоча він насправді потребує лише його цінностей. Або йому це потрібно для глузування. Принаймні, це єдині причини, які я можу собі уявити.
Cubic

9
Модульні тести були б цілком вагомим підставою для цього - знущана служба, що повертає майбутнє зі значеннями тестів.
Луїс Вассерман

3
@Cubic. Як щодо того, якби у вас був метод, який приймає Callable <T>, і хто може або не може виконувати роботу асинхронно, залежно від доступних ресурсів або інших факторів, таких як опції, які вже були надані раніше? Уявіть, якби Executor.execute (Runnable) взяв замість цього Callable <T> як параметр і вирішив запустити його у виконуючому потоці, чи тоді реалізації не потрібно буде створювати власне майбутнє <T>?
Мартін Андерссон,

Відповіді:


66

Apache Commons Lang визначає подібну реалізацію, яка називається ConstantFuture, її можна отримати, зателефонувавши:

Future<T> future = ConcurrentUtils.constantFuture(T myValue);

Дивіться відповідь
Андрейса

201

У Java 8 ви можете використовувати вбудований CompletableFuture:

 Future future = CompletableFuture.completedFuture(value);

Це дасть вам завершене майбутнє. Натомість використовуйте new CompletableFuture ().
zafar142003

8
@ zafar142003 OP запитав про завершене майбутнє, ні?
Andrejs

судячи з класу в деталях запитання (у 2012 р.), я думаю, що ОП хотіла реалізації "Повне майбутнє". Але, мабуть, зараз це спірне питання.
zafar142003

Судячи з класу в деталях запитання, схоже, ОП хотів Майбутнього з негайною цінністю. Дивіться, що isDoneзавжди повертається істиною. Тому це відмінна відповідь.
nathanfranke


2
FutureTask<String> ft = new FutureTask<>(() -> "foo");
ft.run();

System.out.println(ft.get());

роздрукує "foo";

Ви також можете мати майбутнє, яке створює виняток, коли викликається get ():

FutureTask<String> ft = new FutureTask<>(() -> {throw new RuntimeException("exception!");});
ft.run();

-3

Я знайшов дуже подібний клас до вашого в Java rt.jar

com.sun.xml.internal.ws.util.CompletedFuture

Це дозволяє також вказати виняток, який можна викликати, коли викликається get (). Просто встановіть це значення в нуль, якщо ви не хочете створювати виняток.


2
Як правило, використовувати що-небудь у com.sun.*пакеті не є чудовою ідеєю. Ці класи, як правило, вважаються внутрішньою деталлю реалізації і можуть змінюватися в різних версіях Java.
Джеймс Кінгсбері,

-6

У Java 6 ви можете використовувати наступне:

Promise<T> p = new Promise<T>();
p.resolve(value);
return p.getFuture();

3
Я не думаю, що це в основних бібліотеках Java. Яку зовнішню залежність він використовує?
Йорн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.