Coroutine을 여러개 실행했을 때의 문제점

import kotlinx.coroutines.*
import kotlin.system.measureTimeMillis

var counter = 0

fun main() = runBlocking {
    withContext(Dispatchers.Default) {
        massiveRun { counter++ }
    }
}

suspend fun massiveRun(action: suspend () -> Unit) {
    val n = 100
    val k = 1000
    val time = measureTimeMillis {
        coroutineScope {
            repeat(n) {
                launch {
                    repeat(k) { action() }
                }
            }
        }
    }
    println("Counter = $counter")
}

실행결과 
Counter = 40101

Volatile은 동시성 문제를 해결하지 못한다.

Volatile이란?
@Volatile을 붙이면 변수의 값이 메인 메모리에만 저장되며, 멀티 쓰레드 환경에서 메인 메모리의 값을 참조하므로 변수 값 불일치 문제를 해결할 수 있게된다.
다만 CPU캐시를 참조하는 것보다 메인메모리를 참조하는 것이 더 느리므로, 성능은 떨어질 수 밖에 없다.

<https://www.charlezz.com/?p=45959>
@Volatile
var counter = 0

Thread-safe한 데이터 구조

val counter = AtomicInteger()

fun main() = runBlocking {
		withContext(Dispatchers.Default) {
        massiveRun {
            counter.incrementAndGet()
        }
    }
}

실행결과 
Counter = 100000

세밀하게 Thread 제한하기

val counterContext = newSingleThreadContext("CounterContext")
var counter = 0

fun main() = runBlocking {
		withContext(Dispatchers.Default) {
        massiveRun {
            withContext(counterContext) {
                counter++
            }
        }
    }
}

굵게 Thread 제한하기