В чем разница между всеми способами предоставления Executor CompletableFuture (и составными методами)?JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 В чем разница между всеми способами предоставления Executor CompletableFuture (и составными методами)?

Сообщение Anonymous »

Я использую Java CompletableFutures для проекта, и меня немного смутило то, что существует несколько способов передать Executor CompletableFuture для передачи управления другому потоку. Рассмотрим пример, где есть основной поток, затем поток-1 и поток-2 из созданного пула потоков.

Код: Выделить всё

ExecutorService executor = Executors.newFixedThreadPool(2);
CompletableFuture future = CompletableFuture.completedFuture("hello world");

future
.thenCompose(result -> CompletableFuture.supplyAsync(() -> "hi again"));

future
.thenCompose(result -> CompletableFuture.supplyAsync(() -> "hi again!", executor));

future
.thenComposeAsync(result -> CompletableFuture.supplyAsync(() -> "hi again!"), executor);

future
.thenComposeAsync(result -> CompletableFuture.supplyAsync(() -> "hi again!", executor), executor);
По сути, как выполняется каждая часть составленного будущего и в каких потоках?
Я попробовал запустить следующий пример кода, который регистрирует имя потока в стандартный вывод

Код: Выделить всё

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class HelloWorld {

public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
CompletableFuture future = CompletableFuture.completedFuture("hello world");

// Case 0: Print the thread at the beginning of main()
System.out.println("Case 0: main executed on thread: " + Thread.currentThread().getName());

// Case 1: No executor specified for inner supplyAsync
future.thenCompose(result -> {
String threadName = Thread.currentThread().getName();
System.out.println("Case 1 (lambda): executed on thread: " + threadName);
return CompletableFuture.supplyAsync(() -> {
String innerThreadName = Thread.currentThread().getName();
System.out.println("Case 1 (supplyAsync): hi again executed on thread: " + innerThreadName);
return "hi again";
});
}).join();

// Case 2: Executor specified for inner supplyAsync
future.thenCompose(result -> {
String threadName = Thread.currentThread().getName();
System.out.println("Case 2 (lambda): executed on thread: " + threadName);
return CompletableFuture.supplyAsync(() -> {
String innerThreadName = Thread.currentThread().getName();
System.out.println("Case 2 (supplyAsync): hi again! executed on thread: " + innerThreadName);
return "hi again!";
}, executor);
}).join();

// Case 3: Executor specified for thenComposeAsync, but not for inner supplyAsync
future.thenComposeAsync(result -> {
String threadName = Thread.currentThread().getName();
System.out.println("Case 3 (lambda): executed on thread: " + threadName);
return CompletableFuture.supplyAsync(() -> {
String innerThreadName = Thread.currentThread().getName();
System.out.println("Case 3 (supplyAsync): hi again! executed on thread: " + innerThreadName);
return "hi again!";
});
}, executor).join();

// Case 4: Executor specified for both thenComposeAsync and inner supplyAsync
future.thenComposeAsync(result -> {
String threadName = Thread.currentThread().getName();
System.out.println("Case 4 (lambda): executed on thread: " + threadName);
return CompletableFuture.supplyAsync(() -> {
String innerThreadName = Thread.currentThread().getName();
System.out.println("Case 4 (supplyAsync): hi again! executed on thread: "  + innerThreadName);
return "hi again!";
}, executor);
}, executor).join();

// Shutdown the executor
executor.shutdown();
}
}
что привело к следующему выводу

Код: Выделить всё

Case 0: main executed on thread: main
Case 1 (lambda): executed on thread: main
Case 1 (supplyAsync): hi again executed on thread: Thread-0
Case 2 (lambda): executed on thread: main
Case 2 (supplyAsync): hi again! executed on thread: pool-1-thread-1
Case 3 (lambda): executed on thread: pool-1-thread-2
Case 3 (supplyAsync): hi again! executed on thread: Thread-1
Case 4 (lambda): executed on thread: pool-1-thread-1
Case 4 (supplyAsync): hi again! executed on thread: pool-1-thread-1
Результаты мне сложно объяснить.
Это было выполнено с помощью онлайн-компилятора Programiz, поэтому я не уверен, какие у них параметры JVM. условия именования тем.

Подробнее здесь: https://stackoverflow.com/questions/790 ... -a-complet
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Потеря соединения JDBC при использовании CompletableFuture, Executor и Semaphore
    Anonymous » » в форуме JAVA
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous
  • Потеря соединения JDBC при использовании CompletableFuture, Executor и Semaphore
    Anonymous » » в форуме JAVA
    0 Ответы
    10 Просмотры
    Последнее сообщение Anonymous
  • Считается ли перегрузка между статическими методами/методами экземпляра в Java перегрузкой? [дубликат]
    Anonymous » » в форуме JAVA
    0 Ответы
    41 Просмотры
    Последнее сообщение Anonymous
  • Разница между завершением работы и завершением работы службы Executor
    Anonymous » » в форуме JAVA
    0 Ответы
    80 Просмотры
    Последнее сообщение Anonymous
  • Разница между завершением работы и завершением работы службы Executor
    Anonymous » » в форуме JAVA
    0 Ответы
    20 Просмотры
    Последнее сообщение Anonymous

Вернуться в «JAVA»