web-dev-qa-db-ja.com

コルーチンを同期する方法は?

これら2つの方法が同期していることを確認しようとしています。私が気付いたことは、コルーチンはスレッドよりも同期が難しいことです。 start()を呼び出した場合、stop()を呼び出すと、コードが実際に最後に停止することをどのように保証できますか?

_object Test {

    private val coroutine = CoroutineScope(Dispatchers.IO)

    @Synchronized
    fun start() {
        coroutine.launch {
            // some work
        }
    }

    @Synchronized
    fun stop() {
        coroutine.launch {
            // clean up then stop
        }
    }
}
_

私の懸念はstart()を呼び出し、次にstop()を呼び出しますが、実際には最初に実行を停止します。したがって、停止したはずのコードが続行されます。

5
J_Strauton

ブール値でDeferredジョブを使用し、それに対してawait()を使用して完了を待ちます。このようなもの:

fun doSomeWork() {
    GlobalScope.launch(Dispatchers.Main) {
        val isStartingComplete = start().await()
        // await() will wait for the completion of the start() function
        if (isStartingComplete) {
            stop()
        }
    }
}

fun start(): Deferred<Boolean> {
    return GlobalScope.async (Dispatchers.IO) {
        // Do your start work
        true
    }
}

fun stop() {
    // Do your stop work
}
0
omz1990

stop()が呼び出されたときに開始をキャンセルジョブする場合は、ジョブをフィールドに保存します。

object Test {

    private val coroutine = CoroutineScope(Dispatchers.IO)
    private var startedJob : Job? = null

    fun start() {
        startedJob = coroutine.launch {
            // some work
        }
    }

    fun stop() {
        runBlocking { startedJob?.cancelAndJoin() }
        coroutine.launch {
            // clean up then stop
        }
    }
}

-

問題がcalling sequenceの場合-最初に開始し、次に停止します。次に、Testオブジェクトを呼び出すコードを確認して同期する必要があります。

0
Neo