강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

송재백님의 프로필 이미지
송재백

작성한 질문수

기초 탄탄! 독하게 시작하는 Java Part 3(상) : 멀티스레드와 동기화

Spin lock 직접구현 및 성능비교

36강 SpinLock 부분 질문

해결된 질문

작성

·

36

0

public void lock() {
    while (!owner.compareAndSet(false, true))
        LockSupport.parkNanos(1);
}

강의에서 직접 구현하신 스핀락에서 LockSupport.parkNanos()를 사용하셨을 때, 컨텍스트 스위칭이 발생하지 않는다고 설명해주셨는데요.

실제로 예제 코드에서 Thread.getState()로 스레드 상태를 확인해보니, parkNanos() 호출 시 스레드가 TIMED_WAITING 상태로 전환되었다가 지정한 시간이 지나면 RUNNABLE 상태로 바뀌는 것을 확인했습니다.
그렇다면 지정한 시간이 지난 후 RUNNABLE 상태가 되었을 때, 해당 스레드에 대해 컨텍스트 스위칭이 발생하는 것이 아닌지 궁금합니다.

또한 강의에서는 parkNanos()가 실제로 블로킹되는 것이 아니라 내부적으로 스피닝한다고 설명해주셨는데, 만약 그렇다면 스레드 상태가 RUNNABLE이어야 하지 않을까 하는 의문도 들었습니다.
이 부분이 조금 혼란스러워 이렇게 질문드리게 되었습니다.

 

 

답변 1

0

널널한 개발자님의 프로필 이미지
널널한 개발자
지식공유자

생각하시는 것처럼 LockSupport.parkNanos() 호출 시 스레드 상태는 TIMED_WAITING 상태가 될 수 있습니다. 그리고 다시 RUNNALBE 상태가 되는데 TIMED_WAITING 상태가 됐을 때 스위칭 가능성이 완전히 사라지는 것은 아닙니다. 이론상 얼마든지 가능합니다. 다만 이는 내부적으로 벌어지는 일입니다. 보여지는 예제의 lock() 함수는 전체가 원자성을 가지는 것처럼 보더라도 큰 문제가 없기 때문에 사실 상 스위칭이 없는 것으로 보는 것이 좋겠다 판단한 설명이라 이해해주시면 좋겠습니다.

결과를 정리하자면 LockSupport.parkNanos() 호출 시 스레드 상태가 변하는 문제 때문에 혼란스럽게 된 것 같습니다. 그와 관련된 내용은 본인이 조사한 것과 같지만 결과적으로 봤을 때 스위칭 문제와 분리해 생각하고 lock() 메서드는 지속적으로 CPU를 사용하는 방식으로 동기화 문제를 해결하는 것으로 이해하시면 좋겠습니다. 물론 LockSupport.parkNanos() 메서드의 동작 특성 때문에 CPU를 덜 쓰게 되는 구조가 된다는 점을 잘 기억해야 하겠습니다.

끝으로 LockSupport.parkNanos() 메서드는 BLOCKED가 아니라 TIME_WAITING 상태를 유발하며 이는 아예 가게를 닫는(BLOCKED) 것이 아니라 가게를 열어둔 채 잠시 휴식 하는 것입니다. 그러니 이 상태를 RUNNABLE이라 할 수도 없고 그렇다고 BLOCKED라 할 수도 없는 상태 입니다. 한 가지 분명한 것은 스케쥴러 관점에서 TIMEED_WAITING 상태는 제외되는 것이 아니라는 점입니다. 참고하시기 바랍니다. 😄

송재백님의 프로필 이미지
송재백
질문자

답변 감사합니다!

정리하자면, TIME_WAITING 상태는 BLOCKED 상태가 아니기 때문에 컨텍스트 스위칭이 발생할 수도 있고 발생하지 않을 수도 있는 것으로 이해했습니다.
다만, 강의에서는 컨텍스트 스위칭이 발생하지 않는다고 보아도 무방하다고 판단하여 그렇게 가정한 것으로 이해해도 괜찮을까요?

널널한 개발자님의 프로필 이미지
널널한 개발자
지식공유자

사실 스위칭 문제를 분리해 별도로 따져 보는 것이 맞습니다. 스위칭이 중요하다기 보다는 원자성 관점에서 동기화처리가 더 중요하기 때문입니다. 그러니 무방하다기 보다는 별도의 문제로 따로 떼서 생각해야 하므로 '큰 의미를 둘 필요는 없다'로 이해하시면 좋겠습니다. 😄

송재백님의 프로필 이미지
송재백

작성한 질문수

질문하기