簡體   English   中英

什么可能導致給定的示例代碼中的IllegalMonitorStateException

[英]What can cause IllegalMonitorStateException in the given sample code

我正在嘗試學習java並發編程。 請檢查我的示例代碼,並幫助我理解為什么我得到“java.lang.IllegalMonitorStateException”,即使我已調用wait()並在同步上下文中通知。

public class Test {

    public static void main(String[] args) throws Exception {    
        Test t1 = new Test();
        t1.m1();
    }

    private void m1() {
        Example ex = new Example();
        Thread t1 = new Thread(ex);
        t1.start();
        synchronized (ex) {
            System.out.println("waiting");
            try {
                wait();
            } catch (Exception e) {
                e.printStackTrace();
            }    
        }    
    }

    public class Example implements Runnable {    
        @Override
        public void run() {
            System.out.println("Running");
            notifyMethod();
        }

        private void notifyMethod() {
            System.out.println("Notifying");
            synchronized (this) {
                try {
                    Thread.sleep(1000);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                notify();
            }
        }
    }
}

我期待“等待,運行,通知”,但實際輸出是:

waiting
Running
java.lang.IllegalMonitorStateException
Notifying
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:502)
    at examples.Test.m1(Test.java:18)
    at examples.Test.main(Test.java:8)

首先,我認為在Runnable上同步並不是一個好主意( Example你的情況)。 你可以在this上進行同步,或者甚至更好地在一個專用的Object上進行同步, this在我的例子中是lock 編輯:同步上Runnable是一樣的使用this ,但對我來說,它看起來更好。 膽量告訴我可能會有更多的東西,但我不是這個領域的專家。 專用鎖Object總是更好,如果您想了解有關該主題的更多信息,請閱讀本文

然后,在同步lock ,您必須在同一個對象上調用wait()lock.wait() 如果您this同步,則調用this.wait()或只調用wait()

當您想要通知等待線程時,您必須再次lock並在該對象上調用notify()lock.notify() 同步中的監視器和調用notify()的對象都必須是您調用wait()的完全相同的對象。

這是一個有效的代碼:

public class Test {
  public static final Object lock = new Object();

    public static void main(String[] args) throws Exception {    
        Test t1 = new Test();
        t1.m1();
    }

    private void m1() {
        Example ex = new Example();
        Thread t1 = new Thread(ex);
        t1.start();
        synchronized (lock) {
            System.out.println("waiting");
            try {
                lock.wait();
            } catch (Exception e) {
                e.printStackTrace();
            }    
        }    
    }


    public static class Example implements Runnable {    
        @Override
        public void run() {
            System.out.println("Running");
            notifyMethod();
        }

        private void notifyMethod() {
            System.out.println("Notifying");
            synchronized (lock) {
                try {
                    Thread.sleep(1000);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                lock.notify();
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM