작성
·
61
·
수정됨
0
1. 강의 내용과 관련된 질문인가요? 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예
3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예
[질문 내용]
제가 멀티스레드와 동시성 관련해서 제대로 깊게 알아야할거같아서 다시복습으로 듣고있는데 예전에 질문했던 내용과 동일한거같아서 다시 질문드려요 ㅠ 그전에 처음 들어서 헷갈린부분이있었는데 다시들으면서도 설명한 부분이 맞나 싶어서요. 그전에 질문할때도 강의내용이 맞는지에 대한 질문이라 조심스러운부분이고 제가 잘못안다고 생각했는데 짚고넘어가면 좋을거같아서 다시 질문드립니다!
이전 질문 링크: https://inf.run/t3Bbm
71. 스레드의 대기 강의
핵심 질문: 부분(13:30)강의에서 ReentrantLock 락 획득 실패시 대기큐에 WAITING상태라고 설명했는데 BLOCKED 상태가 가맞는지 검토필요.
이부분에 대한 검토가 필요할거같고 제가 잘못알고있다면 참고해야할 링크를 주시면 감사하겠습니다. 아니라면 저처럼 이해하는데 오해의 소지가있는부분이 발생할것같습니다.
질문내용:
부분(13:30)에서 대기1 락을 획득하기위한 대기큐에 대해서 설명해주셨고 lock()호출시에 이미 다른 스레드가 락을 획득시에는 WAITING상태로 대기하고 synchronized인 경우에만BLOCKED인거고 ReentrantLock은 WAITING 상태로 락획득을 대기큐에서 대기한다 라고 설명해주셧는데 이부분이 락이아닌 큐가 꽉차거나 완전히 비어있을때(특정 조건)는 RUNNABLE에서 await()사용해서 WAITING상태로 만들고 이걸 스레드대기공간(집합)에 넣고 추후 명시적으로 깨울수있게하는데, 락획득 실패시에는 BLOCKED상태로 락대기집합에 있는거고, 얻고나서 RUNNABLE상태에서 특정조건에 부합되지않을때(큐가 꽉차거나, 없을때) await를 써서 다시 WAITING상태로 스레드 대기집합에 넣는게 맞는거같아서 검토부탁드립니다.!
그래서 이전강의 notify설명(synchronized 부분이긴하지만)에서도 WAIT -> BLOCKED 설명해주실때 WAIT이던애를 깨우면 바로 RUNNABLE이 되는게아니라 BLOCKED되는 설명부분이랑 ReentrantLock 역시 같은 원리가 맞는거같은데 이부분 다시 검토해주실수있나해서요ㅜ
ReentrantLock 이라고해서 lock얻는걸 실패해도 WAITING이라는건 아닌거같아 검토해주시면 감사하겠습니다..!
그리고 (17:40) synchronized의 경우 blocked일때는 interrupt로 깨우지못한다고했고(이부분설명은 맞는데)
reentrantlock은 lockInterruptibly() 를 사용하면 가능하다고 했는데 이게 WAITING상태여서 가능하다기보단 lockInterruptibly이 BLOCKED상태인 스레드를 InterruptedException가 발생해서 blocked상태에서 빠져나오는게하는 기능인거 같은데 이부분도..
reentrantlock역시 lock()만 사용으로는 못깨우고 이게 WAITING인거랑 좀 별게인거같아서 검토해주실수있을까해서요!
아래 참고 링크를 걸긴했는데 강의들 들으면서 사이클을 생각하다가 락을 획득할려다가 실패시 WAITING으로 대기한다라는게 원리상 아닐거같아서 찾아본게 oracle에서는 명시적으로 나타내진않았고 chat gpt에게 물어보면 제가 계속 waiting이 맞지않냐 blocked은 아니지않냐 공식문서 있냐 물어보면 명시적이진 않지만 유추할수있다 라고도 하고 그래서 결국 찾은 링크가 아래인데 공식은 아니고 블로그 내용이긴해서,, 한번더 영한님이 체크해주실수있을까해서요
아래 chat gpt 답변과 블로그 링크에서 해당 내용부분 스샷도 일부 남길게요!
https://blog.ycrash.io/java-suspended-thread-states-blocked-waiting-timed_waiting/?utm_source=chatgpt.com
------
질문을 남기니 그때처럼 인프런ai가 답변했는데 저 내용이 맞는거같아서요!
답변 2
1
안녕하세요. 김태언님
질문의 핵심이 ReentrantLock에서 lock()을 호출할 때 대기 상태가 되면 BLOCKED 상태가 되는가? 아니면 WAITING 상태가 되는가이지요?
너무 고민하기 보다는 간단한 예시를 만들어서 ReentrantLock 락을 획득하지 못하고 기다리는 스레드의 상태를 출력해보시면 바로 이해가 되실거에요 🙂
사실 BLOCK이라는 표현이 스레드가 대기한다는 중의적인 표현으로 많이 사용되기 때문에 혼란이 있을 수 있는데요. 그래서 GPT나 여러 블로그에서 대기 한다는 표현을 함께 섞어서 이렇게 사용하면서 혼란이 있는 것 같아요. 제가 코드와 테스트로 확인해보았을 때는 WAITING 상태가 맞았습니다.
감사합니다.
1
안녕하세요, 인프런 AI 인턴입니다. 김태언님.
ReentrantLock과 관련된 스레드 상태에 대해 많이 고민하셨군요. 질문 주셔서 감사합니다. ReentrantLock에서의 스레드 대기는 다소 복잡하게 느껴질 수 있습니다. 조금 더 명확하게 정리해보겠습니다.
ReentrantLock의 대기 상태:
lock.lock()
을 호출할 때, 이미 다른 스레드가 해당 Lock을 소유하고 있다면 해당 스레드는 BLOCKED
상태가 됩니다. 이는 락을 얻기 위해 대기해야 하기 때문입니다.condition.await()
를 호출하면 스레드는 WAITING
상태로 전환됩니다. 이는 특정 조건을 기다리는 동안 락을 해제하고, 다른 스레드가 락을 획득할 수 있도록 대기하는 상태입니다. 이 상태에서는 다른 스레드가 condition.signal()
또는 condition.signalAll()
을 호출할 때까지 대기합니다.스레드 상태 전이:
WAITING
상태에서 BLOCKED
로 전이될 수도 있습니다. 이는 락을 다시 획득해야 하는 상황에서 발생할 수 있습니다.WAIT
상태에서 깨어난 스레드는 즉시 RUNNABLE
상태로 가는 것이 아니라, 락을 획득해야 할 때 BLOCKED
상태로 전이되는 것입니다.참고 자료:
ReentrantLock
이 왜 특정 상태에 놓이게 되는지에 대한 논리적 설명을 제공합니다.이미지 참고: 제공해주신 설명 이미지 및 링크는 ReentrantLock의 동작 방식을 이해하는 데 유용한 시각적 자료가 될 것입니다.
지금까지의 설명이 명확하게 이해되셨기를 바라며, 강의에서 다룬 내용과 기존 문의된 질문을 복습하면서 해당 개념이 명쾌해지길 바랍니다. 필요한 경우, 강의의 관련 부분을 다시 검토해보시는 것도 도움이 될 수 있습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
감사합니다 확인했습니다!
실제 코드로 적용해보니 영한님 말씀처럼 WAITING이 찍히고있네요!
영상에서말하는 락 대기큐에 대한 세부내용인 내부적으로 AQS+ park()호출로 JVM 스레드상 WAITING이 나온다는것도 찾았습니다!
다시한번 감사드립니다 ㅠㅠ