0

我刚刚开始玩 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 和虚拟线程之间存在根本不兼容的东西。然而,

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 不兼容的问题?
4

1 回答 1

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 自动创建扩展函数时,我常常感到很沮丧,因为我并不能立即明白要在主体中放入什么,而在这种情况下,我什么也没做,这是错误的。尽管在谷歌上搜索了很多,但我还是很难找到让我找到解决方案的代码,所以它有点碰巧......

结论,一旦你知道一些特殊的黑魔法,应该可以使用 Kotlin 的 Project Loom ......

于 2021-10-28T22:00:12.590 回答