쓰레드 공부하다가 ^^
다온
안녕하세여;;;;;; 너무 궁금한게 하나있어서여;;;;;;;
쓰레드 Guarded Suspention 패턴을 공부하다가 궁금한게 생겨서요.
예제는 쓰레드부분에서 단골로나오는 예제인데여.
생산자랑 소비자 클래스가있어서
생산자가 바구니에 빵을 하나라도 가져다놓으면 소비자가 빵을
가져가구,혹시 바구니에 빵이 없으면 wait하는 예제거든요.
일단 메소드를 보시면요....
class A{
LinkedList pueue = new LinkedList();public synchronized void getBread(){ // 소비자가 빵을 가지고오려한다
while(queue.size()=0){ // 바구니에 빵이하나도 없는지 확인한다
try{
wait(); // 빵이 하나도없다면 wait셋에 빠진다
}catch(Exception e){}
}
queue.removeFirst(); //바구닝 ㅔ빵이 있다면 하나를 가져오고queue의 싸이즈를 -1 한다.
System.out.println(빵을 가져왔습니다);
}
그런데 이상한게..책을 보니까...이런질문이 있더라고요.
동기화메소드안의 바구니에 빵이있나없나 체크하는부분에서 while대신
if를 쓰면 문제점이 있을까요 없을까요?? 전 없을거라고 생각했는데 있다고 하네여 -_-??
책에는 다음과 같이 설명이 되어있는데요.
복수의 쓰레드가 wait하고 있을때 생산자가 빵을 바구니에 하나 넣어놓고 notifyAll()을 호출했다고 합시다.이떄 복수의 쓰레드는 모두 동작하기 시작합니다. 만일 이때 queue.size()의 값이 1이라고 하면 움직이기 시작한 처음의 쓰레드가 queue.removeFirst()를 호출한 결과 queue.size()의 값이 0이 됩니다. 그 결과 움직이기 시작한 두번째의 쓰레드는 queue.size()의 값이 0인데도 queue.removeFirst()를 호출해버리게 됩니다. 때문에 안전성을 잃어버릴 우려가 있습니다.
wait 하고있던 쓰레드는 움직이기 시작하기 전에 조건을 다시한번 체크해야합니다.
따라서 if가 아닌 while을 사용해야합니다라고 나와있는데 이해가 안가네요.
어차피 첫번째 스레드가 동기화메소드에 들어갔다면
두번째 쓰레드는 자연스럽게 블록상태로 될것이고,
첫번째 쓰레드가 빵을 가지고와서 락을 해제하고 나오면 바구니가 0이 되겠죠.
그러면 두번째 쓰레드가 락을 얻어서 동기화메소드로 들어가서 바구니에 빵이 하나이상 들어있나 체크할테고...
0개니까 wait셋 으로 갈것가튼데..
책에서 이야기하는바가 무엇인지 알수없네요..
-
한울
질문입니다.. 그럼 synchronized 키워드는 뭐땜에 쓰는거죠? B 나 C중에 한넘만 검색을 할수 있게되는게 아닌가요?
-
YourWay
\첫번째 스레드가 동기화메소드에 들어갔다면 두번째 쓰레드는 자연스럽게 블록상태로 될것이고,\ 는 맞을수도 있지만 틀릴수도 있죠.
생산자 A가 있고,
B가 빵을 요청하고 , C가 또 빵을 요청한다면,
A가 빵을 넣기전에 B와 C는 wait 하고 있겠죠.
그런데 A가 빵을 넣고나서
과연 누가 빵을 가져 가야 할까요? B 일까요? C 일까요?
즉,
\복수의 쓰레드가 wait하고 있을때
생산자(A)가 빵을 바구니에 하나 넣어놓고 notifyA