patriques
patriques

Reputation: 5201

IllegalMonitorStateException when interrupting threads

Im getting a IllegalMonitorStateException and I feel I cant read more, so Im asking if someone knows what Im doing wrong. Im getting this error at the end of the program running, after the counter (shared resource among threads in the Gate Class) is stuck in waiting. To tell the threads to end I interrupt them from the main method.

The Counter class has amongst others methods whith critical sections.

            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;
    }

The run method in the class Gate (that also have the threads ) :

            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;
    }

The main method has these lines:

            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());
            }
           }

This is driving me crazy, I have read all about the monitor error.

Upvotes: 0

Views: 237

Answers (1)

assylias
assylias

Reputation: 328568

t.wait(); should be in a synchronized(t) block.

However I can't see any t.notifyAll() in your code so it looks like you could wait forever. Also note that the standard idiom is to wait in a loop to deal wit spurious wakeups.

Upvotes: 1

Related Questions