2021-10-29

Can Project Loom be used from Kotlin?

I am just getting started at playing with Project Loom...

Given the Java code which seems to work correctly

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);
        });
    });
}

When IntelliJ converts this to Kotlin I get

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) {

which seems to compile fine, but when executed, nothing is printed on the console?

Is there some latent incompatibility between Kotlin and Project Loom?

Further experiments show that

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

does not print anything, but

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

does print the expected result, so there is something fundamentally incompatible between Kotlin and Virtual Threads. However,

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()}")
        })
    })
}

does not print anything, so there are other issues at play too... Indeed

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

does not print anything, but

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

does print the expected results? Also,

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

prints the expected results, so there is some weirdness with use?

This begs the questions

  1. Are there some problems with how Project Loom is designed/implemented that is causing problems for Kotlin?
    • Are there some problems with JDK-18 that is not compatible with Kotlin?
  2. Are there some problems with how Kotlin is designed/implemented that cannot interoperate with Project Loom?
    • Are there some problems with Kotlin, that are not compatible with JDK-18?


from Recent Questions - Stack Overflow https://ift.tt/2ZINMoe
https://ift.tt/eA8V8J

No comments:

Post a Comment