-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCoroutinesThreads.kt
More file actions
85 lines (77 loc) · 2.69 KB
/
Copy pathCoroutinesThreads.kt
File metadata and controls
85 lines (77 loc) · 2.69 KB
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package tutorial
import kotlin.concurrent.thread
import kotlin.system.measureTimeMillis
import kotlinx.coroutines.experimental.*
fun main(args: Array<String>) {
println("Before calling launch")
launch {
var result = 0
val duration = measureTimeMillis { result = combine() }
println("Result of async combine of three 1 sec functions: $result, duration: $duration ms")
}
/**
* This 'println' will be executed before the 'println' inside 'launch'
* since the main thread will not wait for the completion of code
* inside 'launch'. To execute this println after combined result,
* add 'runBlocking' to main function and remove the launch {};
* this way, main thread will wait for the result and then proceeds
* to next lines
*/
println("After calling launch")
// Compare co-routine vs thread performance
// Threads have major memory / time overhead for over 10K threads
val jobs = 1..20_000
val coRoutingDuration = measureTimeMillis { useCoRoutines(jobs) }
println("${jobs.count()} jobs ran on co-routines in $coRoutingDuration ms")
val threadDuration = measureTimeMillis { useThreads(jobs) }
println("${jobs.count()} jobs ran on threads in $threadDuration ms")
}
/**
* Combine the result of asynchronously executed functions
* using 'await'; Either use 'suspend' keyword or wait for
* the result of suspended functions in a 'launch' or 'runBlocking' block
*/
suspend fun combine() : Int {
// result retrievers are executed asynchronously
val firstResult = async{ retrieve(1) }
val secondResult = async{ retrieve(2) }
val thirdResult = async{ retrieve(3) }
// .await() blocks the thread until the value of async function is returned
return firstResult.await() + secondResult.await() + thirdResult.await()
}
/**
* Keyword 'suspend' indicates that function is blocking
* and it takes time for the function to return a result
* This function is an analogy to IO jobs
*/
suspend fun retrieve(num: Int) : Int {
delay(1000L)
return num * 2
}
fun useThreads(jobs: IntRange){
val threads : MutableList<Thread> = mutableListOf()
jobs.forEach {
val thread = thread {
Thread.sleep(1000L) // 1 second
}
threads.add(thread)
}
threads.forEach {
it.join() // wait for thread completion
}
}
fun useCoRoutines(jobs: IntRange) = runBlocking {
val coRoutines : MutableList<Job> = mutableListOf()
jobs.forEach {
// CommonPool: use a shared thread
// Unconfined: use any thread and skip back and forth
// UI: execute the block inside launch in UI thread (for android)
val job = launch(CommonPool) {
delay(1000L) // 1 second
}
coRoutines.add(job)
}
coRoutines.forEach {
it.join() // wait for co-routine completion
}
}