import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class UserDownloader(
private val api: NetworkService
) {
private val users = mutableListOf<User>()
fun downloaded(): List<User> = users.toList()
suspend fun fetchUser(id: Int) {
val newUser = api.fetchUser(id)
users.add(newUser)
}
}
class NetworkService {
suspend fun fetchUser(id: Int) : User {
delay(2)
return User("User$id")
}
}
class User(val id: String)
suspend fun main() {
val downloader = UserDownloader(NetworkService())
coroutineScope {
repeat(1_000_000) {
launch {
downloader.fetchUser(it)
}
}
}
println(downloader.downloaded().size) // 816051
}
fun main() = runBlocking {
var count = 0
massiveRun {
count++
}
println(count) // 10_000_000 보다 작은 숫자
}
suspend fun massiveRun(action: suspend () -> Unit) {
withContext(Dispatchers.Default) {
repeat(10_000_000) {
launch {
action()
}
}
}
}
fun main() = runBlocking {
var count = 0
val lock = Any()
massiveRun {
synchronized(lock) {
count++
}
}
println(count) // 10000000
}
→ 스레드 블로킹(자원 낭비) 없이 중단하거나 충돌을 회피할 수 있는 방법을 사용해야 한다.
fun main() = runBlocking {
var counter = AtomicInteger()
massiveRun {
counter.incrementAndGet()
}
println(counter.get()) // 10000000
}
fun main() = runBlocking {
var counter = 0
val dispatcher = Dispatchers.IO.limitedParallelism(1)
massiveRun {
withContext(dispatcher) {
counter++
}
}
println(counter) // 10000000
}