작성
·
430
·
수정됨
답변 1
2
안녕하세요, 클래식님!! 정말 좋은 질문 주셔서 감사드립니다!! 🙏🙏
결론부터 말씀드리자면 thread-safe하지 않습니다! 즉, 동시성 문제를 고려해야만 합니다.
https://medium.com/@yangweigbh/how-kotlin-lambda-capture-variable-ef90e11e531d
에서 Kotlin이 변수를 capture 하는 방식을 확인해보실 수 있는데요! 간략히 말씀드리면 어떤 변수를 Object로 만든 다음, 그 Object의 reference를 각 람다가 공유하는 방식입니다.
실제로 코루틴을 활용해 한 변수에 여러 스레드가 동시에 접근하게 하면 의도하지 않은 동작을 확인할 수 있습니다.
@Test
fun lambdaClosureMultiThreadTest(): Unit = runBlocking {
// given
val dispatcher = Executors.newFixedThreadPool(50).asCoroutineDispatcher()
var count = 0 // 람다 밖에 가변 변수를 하나 만든다.
// when
val jobs = (1..1000).map { // (50개 스레드 풀에서) 동시에 count를 1씩 총 1,000번 더한다.
launch(dispatcher) {
count += 1
}
}
jobs.joinAll()
// then
assertThat(count).isEqualTo(1000)
}
위의 코드는 50개 스레드 풀에서 1000개의 코루틴이 하나의 변수 count
에 접근해 1을 더하는 테스트 코드입니다! 이 테스트 코드는 높은 확률로 실패하는데요!!! (제 컴퓨터에서는 998이나 999가 자주 나오더라고요...) 바꿔 말하면 한 변수에 한 thread만 접근할 수 있는 것이 아니라 여러 thread가 동시에 접근할 수 있다는 의미입니다.
혹시나 궁금한 점이 더 있으시다면 편하게 질문 부탁드리겠습니다.
감사합니다. 오늘도 행복한 하루 되세요!! 🙏