2014-11-25 6 views
0

여러 스레드의 동기화에 대한 자습서를 찾고 wait() 및 notifyAll()을 통해이 문제를 해결했지만 나에게 도움이되지 못했습니다. 아마, 내 프로그램은 배열에서 사용 가능한 위치를 확인하는 50 개의 스레드를 시작하고, 대기 모드가없는 경우 대기 모드로 들어간다. 끝나면 notifyAll()은 다시 시작하므로 자유로운 위치를 찾을 수 있습니다. 그러나 이로 인해 IllegalMonitorStateException이 여러 번 발생합니다.Java - wait() 및 notifyAll()

@Override 
public void run() { 
    try { 
     Random rnd = new Random(new Date().getTime()); 
     boolean entrado = false; 
     int i = 0; 
     sm.acquire(); 
     synchronized (biblioteca) { 
      System.out.println("Usuario " + id + " entra"); 
      while (!entrado) { 
       for (i = 0; i < biblioteca.ordenadores.length && !entrado; i++) { 
        if (biblioteca.ordenadores[i] == 0) { 
         entrado = true; 
         break; 
        } 
       } 
       if (!entrado) { 
        System.out.println("Usuario " + id + " en la sala de espera"); 
        wait(); 
       } 
      } 

      biblioteca.ordenadores[i] = id; 
      System.out.println("Usuario " + id + " ocupa Ordenador " + i 
        + "\nOrdenadores: " + biblioteca.muestraOrdenadores()); 
     } 
     Thread.sleep(rnd.nextInt(2000)); 
     synchronized (biblioteca) { 
      System.out.println("Usuario " + id + " termina de usar el Ordenador " + i + " y sale"); 
      biblioteca.ordenadores[i] = 0; 
      notifyAll(); 
     } 
     sm.release(); 

    } catch (InterruptedException e) { 

    } 
} 
+0

'sm'이란 무엇입니까? 'IllegalMonitorStateException'을 던지는 행은 무엇입니까? –

답변

1

당신은 wait()thisnotifyAll()를 호출하고 biblioteca을에 동기화된다. biblioteca.wait()biblioteca.notifyAll()으로 전화해야합니다.

+0

그런 다음 다른 옵션은 Biblioteca에서 동기화 된 메서드를 설정하고 wait() 및 notifyAll()을 호출합니다. 어쨌든, 문제는 해결되었습니다. 고맙습니다. – DSalas

0

, 예외 : IllegalMonitorStateException가 발생합니다 JavaDoc을에 따르면 "스레드가 객체의 모니터에서 대기하거나 지정된 모니터를 소유하지 않고 객체의 모니터에 대기중인 다른 스레드에 통보를 시도한 것을 나타냅니다."

에서 설명한 것처럼 foo.wait() 또는 foo.notify()를 호출하려면 호출 스레드가 foo 객체에 대한 잠금을 소유하고 있어야합니다. 이 예외는, 선행 synchronized (foo) {없이 호출하면 (자) 슬로우됩니다.

출처 : http://www.jguru.com/faq/view.jsp?EID=128732

관련 문제