Home kotlin - coroutines
Post
Cancel

kotlin - coroutines

Advanced kotlin Coroutines tips and tricks

start to use kotlin is very easy, just put long time operation in launch , right ? for simple cases , sure.

1
2
3
4
5
6
7
runBlocking(Dispatchers.IO) {
    withTimeout(1000) {
        val socket = ServerSocket(42)

            socket.accept() // stuck here until some one connected.
    }
}

reference

1
2
3
4
5
6
7
8
9
10
    launch(Dispatchers.Unconfined) { // not confined -- will work with main thread
        println("Unconfined      : I'm working in thread ${Thread.currentThread().name}")
        delay(500)
        println("Unconfined      : After delay in thread ${Thread.currentThread().name}")
    }
    launch { // context of the parent, main runBlocking coroutine
        println("main runBlocking: I'm working in thread ${Thread.currentThread().name}")
        delay(1000)
        println("main runBlocking: After delay in thread ${Thread.currentThread().name}")
    }

Unconfined context, after suspension point , the thread will change to other thread,not the original thread. Unconfined dispatcher should not be used in general code.

code below can produce a multi-thread problem. because sell & sell2 (maybe) run on diffrent thread.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
fun main() {
    runBlocking(CoroutineName("main")) {
        produce()
        sell()
        sell2()
        delay(100000)
    }
}
var items:String = ""

fun produce(){
    GlobalScope.launch(Dispatchers.IO){
        println(Thread.currentThread().name)
        while(isActive){
            delay(Random.nextInt(500,1000).toLong())
//            delay(500)
            items += "A"
//            println("items in produce $items")
        }
    }
}

fun sell(){
    GlobalScope.launch(Dispatchers.Default){
        println(Thread.currentThread().name)
        while(isActive){
            delay(Random.nextInt(500,1000).toLong())
//            delay(500)
            if(items.isNotEmpty()){
                println("1.drop \n$items")
                items = items.substring(0,items.length-1)
                println(items)
            }
        }
    }
}
fun sell2(){
    GlobalScope.launch(Dispatchers.Default){
        println(Thread.currentThread().name)
        while(isActive){
            delay(Random.nextInt(500,1000).toLong())
//            delay(500)
            if(items.isNotEmpty()){
                println("2.drop \n$items")
                items = items.substring(0,items.length-1)
                println(items)
            }
        }
    }
}
This post is licensed under CC BY 4.0 by the author.