2017-01-10 5 views
5

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. ^^^

Odpowiedz

7

Corntines Kotlina są realizowane z transformacją kompilatora do kodu, co oczywiście może być wykonane tylko przez kotlinc.

Tak, nie, Java nie może używać mechanizmu kortynowego Kotlin, ponieważ jest to funkcja kompilacji.

0

Można użyć Thread.sleep() bez wprowadzania żadnej asynchroniczności. Jeśli jednak blokowanie jest problemem (ponieważ musisz skalować ten kod do tysięcy równoległych egzekucji), sugeruję, abyś spojrzał na Quasar.

Powiązane problemy