2017-09-15 3 views
2
private static volatile AtomicInteger blockClientCount = new AtomicInteger(0); 

private static Object lock = new Object(); 

private static Lock reentrantLock = new ReentrantLock(); 

private static Condition condition = reentrantLock.newCondition();  

@Override 
public void run() { 
    Random random = new Random(this.hashCode()); 
    while (true) { 
     String request = random.nextInt(10) + "" + IOUtil.operators[random.nextInt(4)] + (random.nextInt(10) + 1); 
     System.out.println(this.getName() + " send request:" + request); 
     if (socketConnect()) { 
      BufferedReader in = null; 
      PrintWriter out = null; 
      try { 
       out = new PrintWriter(socket.getOutputStream(), true); 
       in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
       blockClientCount.incrementAndGet(); 

       reentrantLock.lock(); 
       try { 
        while (blockClientCount.get() % IOUtil.CLIENNT_NUM != 0) { 
         /** 
         * TODO java.lang.IllegalMonitorStateException 
         */ 
         condition.wait(); 
        } 
        condition.signalAll(); 
       } finally { 
        reentrantLock.unlock(); 
       } 

       // synchronized (lock) { 
       // while (blockClientCount.get() % IOUtil.CLIENNT_NUM != 0) 
       // { 
       // lock.wait(); 
       // } 
       // lock.notifyAll(); 
       // } 
       out.println(request); 
       String response = in.readLine(); 
       System.out.println(this.getName() + " accept response:" + response); 
      } catch (final Exception e) { 
       e.printStackTrace(); 
      } finally { 
       IOUtil.close(in); 
       IOUtil.close(out); 
      } 
     } 
     try { 
      sleep(1000); 
     } catch (InterruptedException e) { 
      System.out.println(this.getName() + " was interrupted and stop"); 
      IOUtil.close(socket); 
      break; 
     } 
    } 
} 

die java.lang.IllegalMonitorStateException wird passieren, wenn ich ReentrantLock verwenden zu warten, aber es funktioniert gut, wenn ich synchronisiert Gebrauch, ich can'not es erklären. Der Grund ist, dass reentrantLock vor condition.wait() entsperrt wird, aber ich weiß nicht warum. Wenn mir jemand helfen kann, muss ich den Code an https://github.com/shanhm1991/demo_io.git sendenjava.lang.IllegalMonitorStateException wenn condition.wait

+3

Mögliches Duplikat von [IllegalMonitorStateException on wait() Anruf] (https://stackoverflow.com/questions/1537116/illegalmonitorstatexception-on-wait-call) –

+0

@VinceEmigh Das ist kein Duplikat dieses speziellen Problems, siehe die akzeptierte Antwort. –

Antwort

2

Das ist, weil Sie die falsche Methode aufrufen. Sie sollten await() statt wait() auf einem Condition Objekt aufrufen:

reentrantLock.lock(); 
try { 
    condition.await(); 
} finally { 
    reentrantLock.unlock(); 
} 

Sie derzeit wait sind aufrufen, die die Object.wait() Methode ist, die Sie auf dem Objekt synchronisiert werden muss, dass Sie es fordern auf. Aber das ist nicht, was Sie wollen, Sie wollen die spezifische Wartefunktionalität der Condition Klasse, und das ist nur durch die Methode await verfügbar.

+0

danke, du hast recht, ich missverstanden. – Aries1991

Verwandte Themen