Аналог ExecutorService в Котлине

У меня есть фрагмент кода Java, который использует ExecutorService. Мне нужно преобразовать этот код в Kotlin с помощью сопрограмм. Я попытался использовать GlobalScope.launch(), который работал, но совсем по-другому. В коде Java есть EXECUTOR_SERVICE.shutdown() и EXECUTOR_SERVICE.awaitTermination, чтобы определить, когда все задачи будут выполнены. Какая реализация будет наиболее близкой к этому в Котлине?

Java-код:

final ExecutorService EXECUTOR_SERVICE =
                Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
for (int d = MIN_DEPTH; d <= maxDepth; d += 2) {
            final int depth = d;
            EXECUTOR_SERVICE.execute(() -> {
                int check = 0;

                final int iterations = 1 << (maxDepth - depth + MIN_DEPTH);
                for (int i = 1; i <= iterations; ++i) {
                    final TreeNode treeNode1 = bottomUpTree(depth);
                    check += treeNode1.itemCheck();
                }
                results[(depth - MIN_DEPTH) / 2] =
                        iterations + "\t trees of depth " + depth + "\t check: " + check;
            });
        }
EXECUTOR_SERVICE.shutdown();
EXECUTOR_SERVICE.awaitTermination(120L, TimeUnit.SECONDS);

Кажется, вопрос подразумевает, что ExecutorService Java недоступен в Kotlin. Хотя автор вопроса, возможно, не имел в виду это, возможно, стоит подчеркнуть для потомков, что Kotlin/JVM имеет доступ ко всем классам платформы Java и всем библиотекам Java, как и в Java.

gidds 08.04.2022 00:35

@gidds Не совсем так, мне интересно, какой идиоматический способ Kotlin реализовать это

Klims 09.04.2022 19:55

Если вы используете IntelliJ, напишите свой код Java, а затем скажите IDE преобразовать его в Kotlin. Он не всегда дает аккуратный, идиоматический Kotlin (на самом деле, иногда он даже не предлагает код компилируемый…), но обычно это очень хорошее место для начала.

gidds 09.04.2022 20:39
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
31
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Kotlin не привязывает пулы потоков к завершению работы, но ваше решение уже было точным переводом. Вам не нужно делать ничего особенного, чтобы дождаться выполнения задач; это делается автоматически launch и каждым методом построения сопрограмм в результате структурированный параллелизм.

Я бы написал это как

val result : List<Int> = runBlocking {
  // you can specify a thread pool, but it looks like you should really use the default one
  (MIN_DEPTH..maxDepth step 2).map { depth ->
    async {
      val check = 0
      val iterations = 1 shl (maxDepth - depth + MIN_DEPTH)
      for (i in 0 until iterations) {
        check += bottomUpTree(depth).itemCheck()
      }
      check
    }
   }.awaitAll()
}

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