2017-08-28 40 views
4

我想學習多線程和練習,我試圖打印奇數&偶數使用兩個線程。我創建了一個對象,它將充當這兩個線程的鎖。當我嘗試執行它時拋出java.lang.IllegalMonitorStateException使用多線程打印奇數和偶數

class EVENODDimpl implements Runnable { 
    int num; 
    int temp = 0; 
    Object lock = new Object(); 

    public EVENODDimpl(int num) { 
     this.num = num; 
    } 

    public void run() { 
     try { 
      synchronized (lock) { 
       while(temp<num) { 
        temp++; 
        System.out.println(Thread.currentThread().getName()+" "+temp); 
        this.notify(); 
        this.wait(); 
       } 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

主要方法:

public class EVENODD { 
    public static void main(String[] args) { 
     int i = 10; 
     EVENODDimpl ei = new EVENODDimpl(i); 
     Thread t1 = new Thread(ei,"EvenThread"); 
     Thread t2 = new Thread(ei,"OddThread"); 
     t1.start(); 
     t2.start(); 
     try { 
      t1.join(); 
      t2.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

我認爲問題是,你正在同步一個對象,但然後調用另一個「通知」和「等待」。 – Tavo

回答

3

waitnotifythis,但你應該waitnotifylock因爲你lock同步,你不能waitnotify其他對象不是你是我的唯一同步,工作版本:

class EVENODDimpl implements Runnable { 
    int num; 
    int temp = 0; 
    Object lock = new Object(); 

    public EVENODDimpl(int num) { 
     this.num = num; 
    } 

    public void run() { 
     try { 
      synchronized (lock) { 
       while(temp<num) { 
        temp++; 
        System.out.println(Thread.currentThread().getName()+" "+temp); 
        lock.notify(); 
        lock.wait(); 
       } 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
3

當它從javadoc

拋出的異常表明某一線程已經試圖等待對象的監視器,或者通知其他線程等待說一個對象的監視器沒有擁有指定的監視器。

這意味着您的方法notifywait應該擁有自己的監視器。換句話說,調用這些方法的對象必須同步。您的this對象不同步。這就是爲什麼你會得到這個例外。在你的情況下,從lock對象調用此方法。

你的邏輯還是錯誤的,但是你需要去探索它。

+0

我已更正並更改鎖定。我可以打印奇數和偶數。我不知道我的邏輯是什麼意思是錯誤的。如果有什麼可以請你指出。 – crazyStart

+1

通過同步您不希望的整個方法concurent或並行執行。那對於整個想法是沒有意義的。也許你需要一些更重要的任務。嘗試解決問題,以及如何解決問題等等。儘管這不是關於這個問題的話題。 –

+0

完全同意你的看法。我正在嘗試學習多線程,因此解決了我在網上找到的問題,但我無法找到相同的練習題。謝謝您的幫助。乾杯 – crazyStart

1

java.lang.IllegalMonitorStateException發生異常是因爲您在對象this.notify()上使用通知方法,但該對象未同步。 更換synchronized (lock)本:synchronized (this)