자바 쓰레드를 보던 중에 의문이 생겼다. 다들 자바의 쓰레드를 사용자 수준 쓰레드라고 하는데, 내가 아는 사용자 수준 쓰레드는 커널이 쓰레드를 모른다는 것이다.
대략 위 그림의 구조대로 cpu->커널->프로세스->쓰레드니까 하나의 쓰레드가 block당하면 모든 쓰레드가 block당하는 것으로 알고 있는데...
자바의 쓰레드는 하나가 block당해도 다른 쓰레드들이 block당하지 않는다. 그리고 위처럼 작동하면 쓰레드가 동시성으로 실행되니 공유자원 문제가 일어날 일이 없지 않나? 라는 생각이 들었다. 그래서 찾아본 결과
https://stackoverflow.com/questions/18278425/are-java-threads-created-in-user-space-or-kernel-space
https://stackoverflow.com/questions/2653458/understanding-javas-native-threads-and-the-jvm
자바의 쓰레드가 사용자 수준 쓰레드는 맞지만, 커널 쓰레드와 1:1 매핑을 통해 동작한다고 한다. 자바는 1.2버전 이전까지 JVM이 쓰레드 스케줄링을 했었으나 이후로는 OS의 정책에 맡기도록 바뀌었다고 한다.
https://en.wikipedia.org/wiki/Green_thread
Green thread - Wikipedia
Lightweight threading implemented in userspace In computer programming, a green thread or virtual thread[disputed – discuss] is a thread that is scheduled by a runtime library or virtual machine (VM) instead of natively by the underlying operating system
OS 대신 런타임 라이브러리나 VM에 의해 쓰레드 스케쥴링하는 기법을 green thread라고 부른다고 한다.
When a green thread executes a blocking system call, not only is that thread blocked, but all of the threads within the process are blocked.[5] To avoid that problem, green threads must use asynchronous I/O operations, although the increased complexity on the user side can be reduced if the virtual machine implementing the green threads spawns specific I/O processes (hidden to the user) for each I/O operation
위키의 위 구절을 보면 green thread가 blocking 시스템 콜을 할 때, 프로세스의 모든 쓰레드가 block 당한다고 한다.
https://stackoverflow.com/questions/5713142/green-threads-vs-non-green-threads
Thus, the advantage is that you get thread-like functionality at all. The disadvantage is that green threads can't actually use multiple cores.
또한 green thread는 OS가 쓰레드 API를 지원하지 않을 때 사용할 수 있고, 실제 쓰레드 같은 기능을 사용할 수 있는 것이 장점이라고 한다. 단점은 green thread는 여러 개의 cpu 코어를 사용할 수 없다는 것이다.
정리하자면 현재 자바의 쓰레드는 사용자 수준 쓰레드가 맞다.
초기 자바 버전에서는 green thread라고 부르는 JVM이 쓰레드를 스케줄링하여 하나의 커널 쓰레드에 여러 개의 사용자 수준 쓰레드를 매핑시키는 방법을 사용하였는데, 그 때문에 한 쓰레드가 block될 경우 모든 쓰레드가 block되는 단점이 있었다.
현재 자바에서는 실행될 때는 JVM이 쓰레드 스케쥴링을 하지 않고 OS에게 스케쥴링을 맡겨 OS의 스케쥴링 정책을 따른다.
그래서 자바의 쓰레드는 커널의 쓰레드의 1:1 매핑하여 동작해서 실제로 병렬성을 만족한다.
https://medium.com/@unmeshvjoshi/how-java-thread-maps-to-os-thread-e280a9fb2e06
자바에서 쓰레드를 만들면 해당하는 커널 쓰레드를 생성하는 native 메서드가 실행돼서 둘이 매핑되는 방식인 것 같다... 자세한 건 위 링크를 참조하면 좋겠다.
내가 이걸 놓쳤었다. 유저 레벨 쓰레드는 세 가지 구현 방식이 있다. 그림을 참조하면 자바 쓰레드는 (b)에 해당한다고 볼 수 있겠다. 이로써 의문이 모두 풀렸다..