0

私は IllegalMonitorStateException を取得しており、これ以上読むことができないと感じているので、誰かが私が何を間違っているのか知っているかどうか尋ねています。カウンター(ゲートクラスのスレッド間の共有リソース)が待機中にスタックした後、実行中のプログラムの最後にこのエラーが発生します。スレッドに終了を指示するために、メイン メソッドから割り込みます。

Counter クラスには、特にクリティカル セクションを持つメソッドがあります。

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

クラス Gate の 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;
    }

main メソッドには次の行があります。

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

これは私を夢中にさせています。モニターエラーについてすべて読みました。

4

1 に答える 1

1

t.wait();ブロックにある必要がありsynchronized(t)ます。

ただし、コードに何も表示されないt.notifyAll()ため、永遠に待つことができるようです。また、標準的なイディオムは、偽のウェイクアップに対処するためにループで待機することです。

于 2013-03-28T01:45:10.893 に答える