Можно ли использовать Project Loom из Котлина?

Я только начинаю играть с Project Loom ...

Учитывая код Java, который, кажется, работает правильно

      try (ExecutorService executor = Executors.newVirtualThreadExecutor()) {
    IntStream.range(0, 16).forEach(i -> {
        System.out.println("i = " + i + ", Thread ID = " + Thread.currentThread());
        executor.submit(() -> {
            var thread = Thread.currentThread();
            System.out.println("Thread ID = " + thread);
        });
    });
}

Когда IntelliJ преобразует это в Kotlin, я получаю

      Executors.newVirtualThreadExecutor().use { executor ->
    IntStream.range(0, 16).forEach(IntConsumer { i: Int ->
        println("i = $i, Thread ID = ${Thread.currentThread()}")
        executor.submit(Runnable {
            println("Thread ID = ${Thread.currentThread()}")
        })
    })
}

private fun ExecutorService.use(block: (ExecutorService) -> Unit) {

который, кажется, компилируется нормально, но при выполнении ничего не печатается на консоли?

Есть ли какая-то скрытая несовместимость между Kotlin и Project Loom?

Дальнейшие эксперименты показывают, что

      Executors.newVirtualThreadExecutor()
    .submit(Runnable { println("Thread = ${Thread.currentThread()}") })

ничего не печатает, но

      Executors.newCachedThreadPool()
    .submit(Runnable { println("Thread = ${Thread.currentThread()}") })

выводит ожидаемый результат, поэтому между Kotlin и VirtualThreads есть что-то принципиально несовместимое. Тем не мение,

      Executors.newCachedThreadPool().use { executor ->
    IntStream.range(0, 16).forEach(IntConsumer { i: Int ->
        println("i = $i, Thread ID = ${Thread.currentThread()}")
        executor.submit(Runnable {
            println("Thread ID = ${Thread.currentThread()}")
        })
    })
}

ничего не печатает, поэтому есть и другие проблемы ...

      Executors.newCachedThreadPool().use { executor ->
    IntStream.range(0, 16).forEach(IntConsumer { i: Int ->
        println("i = $i, Thread ID = ${Thread.currentThread()}")
    })
}

ничего не печатает, но

      IntStream.range(0, 16).forEach(IntConsumer { i: Int ->
    println("i = $i, Thread ID = ${Thread.currentThread()}")
})

печатает ожидаемые результаты? Также,

      IntStream.range(0, 16).forEach(IntConsumer { i: Int ->
    println("i = $i, Thread ID = ${Thread.currentThread()}")
    executor.submit(Runnable {
        println("Thread ID = ${Thread.currentThread()}")
    })
})

печатает ожидаемые результаты, поэтому есть некоторая странность с use?

Это вызывает вопросы

  1. Есть ли проблемы с разработкой / реализацией Project Loom, которые вызывают проблемы для Kotlin?
    • Есть ли проблемы с JDK-18, несовместимым с Kotlin?
  2. Есть ли какие-то проблемы с тем, как разработан / реализован Kotlin, которые не могут взаимодействовать с Project Loom?
    • Есть ли проблемы с Kotlin, несовместимые с JDK-18?

1 ответ

Проблема заключалась в том, что я не определял useрасширение функционирует должным образом. Простое исправление

      private fun ExecutorService.use(block: (executorService: ExecutorService) -> Unit) = block(this)

А сейчас

      Executors.newVirtualThreadExecutor().use { executorService ->
    IntStream.range(0, 16).forEach(IntConsumer { i: Int ->
        println("i = $i, Thread ID = ${Thread.currentThread()}")
        executorService.submit(Runnable {
            println("Thread ID = ${Thread.currentThread()}")
        })
    })
}

производит вывод, аналогичный примеру Java

      i = 1, Thread ID = Thread[#1,main,5,main]
i = 2, Thread ID = Thread[#1,main,5,main]
Thread ID = VirtualThread[#19]/runnable@ForkJoinPool-1-worker-1
Thread ID = VirtualThread[#20]/runnable@ForkJoinPool-1-worker-2
i = 3, Thread ID = Thread[#1,main,5,main]

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

В заключение, можно будет использовать Project Loom из Котлина, если вы познаете какую-то особую черную магию ... 🥳

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