我的目标是什么?
我的目标是能够使用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() funasync(block: suspend () -> T): CompletableFuture { val future = CompletableFuture () block.startCoroutine(completion = object : Continuation { override fun resume(value: T) { future.complete(value) } override fun resumeWithException(exception: Throwable) { future.completeExceptionally(exception) } }) return future } suspend fun await(f: CompletableFuture ): T = suspendCoroutine { c: Continuation -> 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) { 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的协同机制,因为它是一个编译时功能.