단일 스레드 환경에서 보통 사용하는 용어이다. 함수가 실행 도중에 중단될 수 있고, 동일한 스레드에서 동일한 함수를 다시 호출해도 안전하다면 재진입(reentrant) 가능하다고 할 수 있다.
다중 스레드 환경에서 보통 사용되며, 여러 스레드가 동시에 동일한 함수를 실행할 수 있는 경우 thread-safe 하다고 할 수 있다. 표준 라이브러리에 있는 함수나 자료구조를 사용할 경우, 공식 문서에서 thread-safe 여부를 확인해서 사용해야 한다.
// non-thread-safe & non-reentrant
var temp: Int
val notThreadSafeAndNotReentrant: (Int) -> Int = { input ->
temp = input
temp + 10
}
// non-thread-safe & reentrant
val notThreadSafeAndReentrant: (Int) -> Int = { input ->
temp = input
input + 10
}
// thread-safe & non-reentrant
val threadSafeTemp: ThreadLocal<Int> = ThreadLocal()
val threadSafeAndNotReentrant: (Int) -> Int = { input ->
threadSafeTemp.set(input)
threadSafeTemp.get() + 10
}
// thread-safe & reentrant
val threadSafeAndReentrant: (Int) -> Int = { input -> input + 10 }
모든 함수를 thread-safe 하게 구현할 수 있지만, 그에 따른 성능 비용이 발생한다. Stack의 외부에서 memory에 접근해야 하는 한, 모든 함수를 reentrant 하게 만들 수는 없다. 따라서 best effort로 모든 함수에 대해 reentrant를 고려하며, 필요에 따른 thread-safe이 동반되어야 한다.