2017-04-15 66 views
0

我想打印或者使用三個線程。 第一線應打印一個號碼,然後第二個線程的第二個數字,然後第三thread.I嘗試使用共享靜態整數來實現它,但我的代碼表明IllegalMonitorStateException.Can請人檢查並告訴我的錯誤?爲什麼IllegalMonitorStateException?

class ThreadRevisit extends Thread 
{ 
static Integer number; 
int num; 
ThreadRevisit(String name,Integer number,int num) 
{ 
    super(name); 
    this.number=number; 
    this.num=num; 
} 

public void run() 
{ 
    int n= number; 
    do 
    { 
    synchronized(ThreadRevisit.number) 
     { 
      if(n>100) 
      { 
      number.notifyAll(); 
      break; 
      } 
      if (n%3==num) 
      { 
       System.out.println(Thread.currentThread().getName()+" "+num); 
       number=number+1; 
      } 
      number.notifyAll(); 
      try 
      { 
      number.wait(); 
      }catch(Exception e) 
      { 

      } 
     } 
    } 
    while(true); 

    } 
} 
class T1 
{ 
public static void main(String[] ar) 
{ 
Integer inn=new Integer(0); 
ThreadRevisit.number=inn; 
ThreadRevisit t1=new ThreadRevisit("one",inn,0); 
ThreadRevisit t2=new ThreadRevisit("two",inn,1); 
ThreadRevisit t3=new ThreadRevisit("three",inn,2); 

t1.start(); 
t2.start(); 
t3.start(); 
} 

回答

0

在第27行

number=number+1; 

你有效地修改對象數量到一個新的增加值。所以新的沒有附加監視器,並導致錯誤。

0

我看到你的代碼中的問題(居然馬爾辛Krasowski提到的相同):你重新分配整型變量。這意味着還有另外一個實例在運行,等待/通知將發生在錯誤的Integer對象上。

我從來沒有挺喜歡等待/通知方法,你也可以看看使用觀察者模式,其中第二線程觀察第一個線程都寫它的輸出和第三線觀察第二的是相同的。

0

IllegalMonitorStateException

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

正如Marcin Krasowski所說,數字已經改變。 您鎖定數與

synchronized(ThreadRevisit.number) 

後來更改了number

通過您呼叫notifyAll()的時候,你沒有上您最初獲得鎖的編號對象上的鎖。

應該避免改變對象,在其上獲取鎖。

相關問題