Jaki jest mój cel?Czy mogę skorzystać z Coroutines Kotlina, używając ich w kodzie Java?
Moim celem jest być w stanie używać systemu Corlogine Kotlina z Javy. Chcę mieć możliwość wstrzymania połowy egzekucji na określony czas, a następnie odebrać kopię zapasową w tym miejscu po upływie określonego czasu. Z Java, chciałbym być w stanie wykonać zadania, które pozwalają zatrzymując połowie wykonanie bez w sposób asynchroniczny, takie jak:
//example 1
someLogic();
pause(3000L); //3 seconds
someMoreLogic();
//example 2
while(true) {
someContinuedLogic();
pause(10000L); //10 seconds
}
Jaki jest mój problem?
Zgodnie z oczekiwaniami, jestem w stanie wykonywać coroutiny doskonale od Kotlina, ale jeśli chodzi o Javę, staje się to trudne, ponieważ część kodu Java wykonuje cały blok na raz bez żadnych przerw, podczas gdy blok Kotlin poprawnie zatrzymuje 1, a następnie 4 sekundy.
Jakie jest moje pytanie?
Czy możliwe jest użycie Kotlin jako szkieletu dla korporacji w Javie? Jeśli tak, co robię źle? Poniżej znajduje się kod źródłowy pokazujący, w jaki sposób próbuję używać coroutines Kotlin w Javie.
KtScript Klasa
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 Code Execution
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 Wykonanie Wyniki
Executing Kotlin script from Kotlin...
1 second passed...
5 seconds passed...
Finished!
Java Code Execution
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!");
}
}
Wykonanie Java Wyniki
Executing Kotlin script from Java...
1 second passed...
5 seconds passed...
Finished!
^^^ Niestety, przerwy są pomijane w Javie. ^^^