kotlinコンカレントの簡単な例の説明

5554 ワード

1、概要


kotlinコヒーレンスは、プロジェクトで同期シリアル呼び出しに使用されることが多い.同時呼び出しではasyncを使うことは知っていますが、はっきりしないものもあります.asynicにはlazyモードもあります.だから簡単な例を書いて理解しやすいです.

2、例


2.1

    fun test1() {
        GlobalScope.launch {
            val old = System.currentTimeMillis()
            Log.d("lee", "----test1---")

            val a1 = async {
                delay(1000)
                Log.d("lee", "delay-1000  timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
            }

            val a2 = async(start = CoroutineStart.LAZY) {

                delay(2000)
                Log.d("lee", "delay-2000  timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
            }

            val a3 = async {
                delay(3000)
                Log.d("lee", "delay-3000  timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
            }

            //a1,a3 ,a2 
            Log.d("lee", "+++ timeOff= ${(System.currentTimeMillis() - old) / 1000L}\"")
        }
        Log.d("lee", "***out***GlobalScope***")
    }

出力結果:
2020-06-17 22:32:13.166 4588-4646/com.leon.myapplication D/lee: ----test1---
2020-06-17 22:32:13.175 4588-4588/com.leon.myapplication D/lee: ***out***GlobalScope***
2020-06-17 22:32:13.178 4588-4646/com.leon.myapplication D/lee: +++ timeOff= 0"
2020-06-17 22:32:14.180 4588-4647/com.leon.myapplication D/lee: delay-1000  timeOff= 1
2020-06-17 22:32:16.186 4588-4647/com.leon.myapplication D/lee: delay-3000  timeOff= 3

表現したい結論:lazy以外のasyncコードブロックは、直接実行されます.Lazyは実行されません

2.2

fun test2() {
        GlobalScope.launch {
            val old = System.currentTimeMillis()
            Log.d("lee", "---test2----")
            
            val a1 = async {
                delay(1000)
                Log.d("lee", "delay-1000  timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
            }

            val a2 = async(start = CoroutineStart.LAZY) {

                delay(2000)
                Log.d("lee", "delay-2000  timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
            }

            val a3 = async {
                delay(3000)
                Log.d("lee", "delay-3000  timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
            }

            //a1,a3 ,a2 
            Log.d(
                "lee",
                "  a1=${a1.await()}  a3=${a3.await()} timeOff= ${(System.currentTimeMillis() - old) / 1000L}\""
            )

            Log.d("lee", " +++ timeOff= ${(System.currentTimeMillis() - old) / 1000L}\"")
        }
        Log.d("lee", "***out***GlobalScope***")
    }

しゅつりょく
2020-06-17 22:37:00.636 5725-5725/com.leon.myapplication D/lee: ***out***GlobalScope***
2020-06-17 22:37:00.636 5725-5758/com.leon.myapplication D/lee: ---test2----
2020-06-17 22:37:01.640 5725-5759/com.leon.myapplication D/lee: delay-1000  timeOff= 1
2020-06-17 22:37:03.642 5725-5759/com.leon.myapplication D/lee: delay-3000  timeOff= 3
2020-06-17 22:37:03.643 5725-5759/com.leon.myapplication D/lee:   a1=28  a3=28 timeOff= 3"
2020-06-17 22:37:03.643 5725-5759/com.leon.myapplication D/lee:  +++ timeOff= 3"

表現の結論:lazy以外のasyncはawaitを呼び出すとその実行が完了するまでブロックされます

2.3

 fun test3() {
        GlobalScope.launch {
            val old = System.currentTimeMillis()
            Log.d("lee", "---test3----")

            val a1 = async {
                delay(1000)
                Log.d("lee", "delay-1000  timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
            }

            val a2 = async(start = CoroutineStart.LAZY) {

                delay(2000)
                Log.d("lee", "delay-2000  timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
            }

            val a3 = async {
                delay(3000)
                Log.d("lee", "delay-3000  timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
            }
            
            Log.d(
                "lee",
                "  a1=${a1.await()}  a3=${a3.await()},timeOff= ${(System.currentTimeMillis() - old) / 1000L}\""
            )
            Log.d("lee", " a2, a2 lazy , await ")
            a2.await()

            Log.d("lee", "  +++ timeOff= ${(System.currentTimeMillis() - old) / 1000L}\"")
        }
        Log.d("lee", "***out***GlobalScope***")
    }
2020-06-17 22:39:16.659 6274-6274/com.leon.myapplication D/lee: ***out***GlobalScope***
2020-06-17 22:39:16.659 6274-6309/com.leon.myapplication D/lee: ---test3----
2020-06-17 22:39:17.664 6274-6309/com.leon.myapplication D/lee: delay-1000  timeOff= 1
2020-06-17 22:39:19.668 6274-6309/com.leon.myapplication D/lee: delay-3000  timeOff= 3
2020-06-17 22:39:19.670 6274-6309/com.leon.myapplication D/lee:   a1=28  a3=28,timeOff= 3"
2020-06-17 22:39:19.670 6274-6309/com.leon.myapplication D/lee:  a2, a2 lazy , await 
2020-06-17 22:39:21.676 6274-6310/com.leon.myapplication D/lee: delay-2000  timeOff= 5
2020-06-17 22:39:21.677 6274-6310/com.leon.myapplication D/lee:   +++ timeOff= 5"



表現したい結論:lazyモードのasynicはawaitを呼び出したときに実行を開始し、そこで実行が完了するまでブロックされます.