我可以通过在Java代码中使用它们来利用Kotlin的协同程序吗?

我的目标是什么?

我的目标是能够使用Java的Kotlin的Coroutine系统。 我希望能够暂停执行一段时间,然后在给定的时间过去之后在那个位置重新找回。 从Java,我希望能够执行任务,而不是以异步方式暂停执行中间执行,例如:

//example 1 someLogic(); pause(3000L); //3 seconds someMoreLogic(); //example 2 while(true) { someContinuedLogic(); pause(10000L); //10 seconds } 

我的问题是什么?

正如所料,我能够从Kotlin中完美地执行协程,但是对于Java来说,它变得棘手,因为代码的Java部分立即执行整个块而没有任何暂停,而Kotlin块正确地暂停1,并且然后4秒。

我的问题是什么?

甚至有可能使用Kotlin作为Java协程的主干? 如果是这样,我做错了什么? 下面你可以找到显示我如何尝试在Java中使用Kotlin协程的源代码。

KtScript类

 abstract class KtScript { abstract fun execute() fun <T> async(block: suspend () -> T): CompletableFuture<T> { val future = CompletableFuture<T>() block.startCoroutine(completion = object : Continuation<T> { override fun resume(value: T) { future.complete(value) } override fun resumeWithException(exception: Throwable) { future.completeExceptionally(exception) } }) return future } suspend fun <T> await(f: CompletableFuture<T>): T = suspendCoroutine { c: Continuation<T> -> f.whenComplete { result, exception -> if (exception == null) c.resume(result) else c.resumeWithException(exception) } } fun pause(ms: Long): CompletableFuture<*> { //todo - a better pausing system (this is just temporary!) return CompletableFuture.runAsync { val currentMs = System.currentTimeMillis() while (System.currentTimeMillis() - currentMs < ms) { /* do nothing */ } } } } 

Kotlin执行代码

 fun main(args: Array<String>) { ScriptTestKotlin().execute() } class ScriptTestKotlin : KtScript() { override fun execute() { println("Executing Kotlin script from Kotlin...") val future = async { await(pause(1000L)) println(" 1 second passed...") await(pause(4000L)) println(" 5 seconds passed...") } future.get() //wait for asynchronous task to finish println("Finished!") } } 

Kotlin执行结果

 Executing Kotlin script from Kotlin... 1 second passed... 5 seconds passed... Finished! 

Java执行代码

 public class ScriptTestJava extends KtScript { public static void main(String[] args) { new ScriptTestJava().execute(); } @Override public void execute() { System.out.println("Executing Kotlin script from Java..."); CompletableFuture<?> future = async(continuation -> { await(pause(1000L), continuation); System.out.println(" 1 second passed..."); await(pause(4000L), continuation); System.out.println(" 5 seconds passed..."); return continuation; }); try { future.get(); //wait for asynchronous task to finish } catch(Exception e) { e.printStackTrace(); } System.out.println("Finished!"); } } 

Java执行结果

 Executing Kotlin script from Java... 1 second passed... 5 seconds passed... Finished! 

不幸的是,这些暂停在Java中被跳过了。 ^^^

Kotlin协程是通过编译器转换来实现的,显然只能通过kotlinc来完成。

所以,不,Java不能使用Kotlin的协程机制,因为它是一个编译时的特性。

您可以使用Thread.sleep()而不引入任何异步性。 然而,如果阻塞是个问题(因为你需要将这个代码扩展到数千个并行执行),我建议你看一下Quasar 。