Quasar invokeAny

Я написал ExecutorService, который используется для параллельного выполнения нескольких потоков и получения первого найденного результата. Для этого я использую метод invokeAny.

Что-то похожее на следующее:

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class Test {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        Set<Callable<String>> callables = new HashSet<Callable<String>>();

        callables.add(new Callable<String>() {
            public String call() throws Exception {
                System.out.println("Task 1 started...");
                return "Task 1 Finished";
            }
        });


        callables.add(new Callable<String>() {
            public String call() throws Exception {
                System.out.println("Task2 started...");
                return "Task 2 Finished";
            }
        });

        callables.add(new Callable<String>() {
            public String call() throws Exception {
                return "Task 3 Finished";
            }
        });

        try {
            String result = executorService.invokeAny(callables);
            System.out.println("result = " + result);
        } catch (Throwable e) {
            e.printStackTrace();
        }

        executorService.shutdown();
    }

}

Все работает нормально, но поскольку мой код выполняет много потоков, используется огромное количество ресурсов (ЦП). Поэтому я заглянул в интернет и обнаружил, что люди предлагают использовать Quasar для решения подобных проблем... Исходя из спецификации, он должен работать как "параллельный" фреймворк java, поэтому я посмотрел и нашел класс "FiberExecutorScheduler", который кажется многообещающим, но я не могу найти способ организовать свою работу, чтобы реализовать то же поведение моего предыдущего кода.

Есть ли способ реализовать это с помощью Quasar? Можете ли вы привести пример? Любая помощь будет оценена.

1 ответ

Согласно документации по волокну, вы можете перевести ваш Callable в Fiber согласно приведенному ниже коду, где V - ваш тип возврата.

new Fiber<V>() {
  @Override
  protected V run() throws SuspendExecution, InterruptedException {
        // your code
    }
}.start();

И вы можете перевести ExecutorService к FiberExecutorSchedulerкуда можно позвонить newFiber добавить ваше волокно к исполнителю.

Мне не хватало документации для этой библиотеки. Нет примеров использования, даже на их собственном сайте. Заглядывая в их репо, я нашел следующий тестовый пример.

@Test
public void simpleTest1() throws Exception {
    final CompletableFuture<String> fut = new CompletableFuture<String>();

    final Fiber<String> fiber = new Fiber<>(scheduler, () -> {
        try {
            return AsyncCompletionStage.get(fut);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
    }).start();

    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(200);
                fut.complete("hi!");
            } catch (InterruptedException e) {
            }
        }
    }).start();

    assertThat(fiber.get(), equalTo("hi!"));

}

Я бы попробовал продолжить на основе этого теста на вашем месте.

Другие вопросы по тегам