2013-03-28 74 views
0

我得到一個IllegalMonitorStateException,我覺得我不能讀更多,所以我問如果有人知道我做錯了什麼。在程序運行結束時,在計數器(Gate Class中的線程之間的共享資源)停留在等待狀態之後,我得到這個錯誤。爲了告訴線程結束,我將它們從主要方法中斷。IllegalMonitorStateException當中斷線程

計數器類除其他方法包括關鍵部分。

  private int currentValue; /* to keep score of people passing */ 

      /* critical section */ 
    public synchronized boolean isFull() { 
     if(busy) { /* lock */ 
      try { 
       wait(); 
      } catch (InterruptedException e) { 
       System.out.println("isFull was interrupted waiting"); 
      } 
     } 
     busy=true; 
        /* is not full notify threads waiting to resume work*/ 
     if(currentValue < maxValue) { 
      notify(); 
      busy=false; /* unlock */ 
      return false; 
     } 
        /* do not notify threads */ 
     return true; 
    } 

      /* critical section */ 
    public synchronized void addPersons() { 
     if(busy) { 
      try { 
       wait(); 
      } catch (InterruptedException e) { 
       System.out.println("addPersons was interrupted waiting"); 
      } 
     } 
     busy=true; 
     currentValue += nr_p; 
     notify(); 
     busy=false; 
    } 

      public synchronized int getValue() { 
     return currentValue; 
    } 

在類門的run方法(也有線程):

  public void run() { 
     while(!blocked) { 
      int waitTime = (r.nextInt(5) + 1) * 1000; /* random seconds */ 
      if(counter.isFull(gatenr)) 
       try { 
         t.wait(); /* here is where the IllegalMonitorStateException occurs. */ 
       } catch (InterruptedException e) { 
        System.out.println("Shutting gate off from waiting"); 
       } 
      if(t.isInterrupted()) { /* check if thread is interrupted */ 
       System.out.println("breaking"); 
       break; 
      } 
      counter.addPersons(1); 
      nrOfPassengers++; 
      try { 
       Thread.sleep(waitTime); 
      } catch (InterruptedException e) { 
       System.out.println("Shutting gate off from sleep"); 
      } 
     } 
    } 

     /* used by main to interrupt threads from wait statement and close gate */ 
    public synchronized void close() { 
     t.interrupt(); 
     blocked = true; 
    } 

主要方法有以下線路:

  while(counter.getValue() < MAX) { 
       Thread.sleep(3000); 
      } 
      System.out.println("Announcement: Ship is full!"); 


      /* wait for child threads to finish */ 
      for(Gate g: gates) { 
       g.close(); /* interrupts thread in gate object */ 
       System.out.println(g.getNoOfPassangers() + " passed through gate nr " + g.getId()); 
      } 
      } 

這是推動我瘋了,我已閱讀有關顯示器錯誤的所有信息。

+0

來自文檔:拋出以指示線程嘗試在對象的監視器上等待,或通知其他線程等待對象的監視器而不擁有指定的監視器。 – Jayan 2013-03-28 01:31:13

+0

創建用於鎖定的成員變量。並呼籲等待。它有點幫助。看到一些在http://stackoverflow.com/questions/2536692/a-simple-scenario-using-wait-and-notify-in-java – Jayan 2013-03-28 01:32:21

回答

1

t.wait();應該在synchronized(t)塊中。

但是我看不到任何t.notifyAll()在你的代碼中,所以它看起來像你可以永遠等待。另外請注意,標準習慣用法是等待一個循環來處理虛假的喚醒。