2013-03-28 77 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()在你的代码中,所以它看起来像你可以永远等待。另外请注意,标准习惯用法是等待一个循环来处理虚假的唤醒。