2017-04-15 74 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()的时候,你没有上您最初获得锁的编号对象上的锁。

应该避免改变对象,在其上获取锁。