首先请看代码:

packageclone;

/**
*生产者与消费者的问题
*/
importjava.util.*;
publicclassRun{
publicstaticvoidmain(String[]args){
Producerp=newProducer();
Consumerc=newConsumer();
newThread(p,"p").start();//start时就会调用produce()
newThread(c,"c").start();//start时就会调用consumption()
}
}

classProducerimplementsRunnable{
publicProducer(){
if(null==goods)goods=newArrayList<Goods>();
}
@Override
publicvoidrun(){
try{
synchronized(Run.class){
if(5>goods.size())
for(inti=goods.size();i<5;i++)
produce();
}
}
catch(Exceptionerr){err.printStackTrace();}
}
publicvoidproduce()throwsException{//生产
System.out.println("coming!thecurrentthreadis"+Thread.currentThread().getName());
intsize=goods.size()+1;
Stringname=String.valueOf(size);
goods.add(newGoods(size,name,Double.parseDouble(name)));
}
privatestaticList<Goods>goods;
publicstaticList<Goods>obtainedGoods(){
System.out.println(Thread.currentThread().getName()+":"+goods.size());returngoods;}
}

classConsumerimplementsRunnable{
@Override
publicvoidrun(){
try{
synchronized(Run.class){
goods=Producer.obtainedGoods();
if(null==goods)System.out.println(Thread.currentThread().getName()+":"+"donothavethiskindofgoods!");
if(0==goods.size())
{
System.out.println(Thread.currentThread().getName()+":"+"thisgoodshavebeendonenothave!wemustwaitforproduce");
this.wait();
}
consumption();
this.notify();
}
}
catch(Exceptionerr){
err=newIllegalMonitorStateException(Thread.currentThread().getName());
err.printStackTrace();
}
}
publicvoidconsumption()throwsException{//消费
System.out.println("coming!thecurrentthreadis"+Thread.currentThread().getName());
Goodsg;
inti=goods.size();
while(0!=i){
g=(Goods)goods.get(i-1);
g.displays();
i--;
}
}
privateList<Goods>goods;
}

classGoods{//商品类
privateintid;
privateStringname="goods";
privatedoubleprice;
publicGoods(intid,Stringname,doubleprice){this.id=id;this.name=this.name+name;this.price=price;}
publicvoiddisplays(){//显示商品
System.out.println(Thread.currentThread().getName()+":"+"id="+id+",name="+name+",price"+price);
}
}


以上代码会报错,报错说是:
java.lang.IllegalMonitorStateException:c
atclone.Consumer.run(Run.java:59)
atjava.lang.Thread.run(Thread.java:619)

这个代码中,抛的异常也是我自定义的,比如上面报错中java.lang.IllegalMonitorStateException:c,
这里的c是发生异常时所运行的线程!!!

也就是说,在c线程运行时,发生了异常,这正是我自定义异常的目的!

--------------------------------------------
然而,问题却来了:
JDK1.6所述:
wait()、notify()必须:当前线程必须拥有此对象监视器
IllegalMonitorStateException-如果当前线程不是此对象监视器的所有者。

我在Consumer类中写的wait()和notify()方法!线程c就是Consumer的对象c对应的那个线程!!!
那么,wait()notify()方法就应该是在本对象的监视器范围内!!!
既然如此,怎么会抛出IllegalMonitorStateException异常呢?

我初学多线程,求指教!

10 个解决方案

#1


之前发帖说错了一句话,
-----------------------------
这个代码中,抛的异常也是我自定义的,比如上面报错中java.lang.IllegalMonitorStateException:c,
这里的c是发生异常时所运行的线程!!!

也就是说,在c线程运行时,发生了异常,这正是我自定义异常的目的!
-----------------------------
我指的是,我就是想,出现异常时,找到是哪个线程发生的异常!

更多相关文章

  1. Maven:主线程中的NoClassDefFoundError
  2. java线程池使用场景和使用方法较详细文摘
  3. java中多线程安全问题产生&解决方案——同步方法

随机推荐

  1. Mysql中FIND_IN_SET()和IN区别简析
  2. 在H2数据库中插入时间——函数“PARSEDAT
  3. beego_mysql,redis,mongo连接(20170307)
  4. 如何在MySQL数据库和JPA中使用Spring Boo
  5. 由于底层异常,无法加载连接类:'java.lang.N
  6. Mysql中文查询问题总结
  7. c#操作mysql事务是不是要在一个数据库连
  8. Mysql索引基础原理
  9. MySQL 示例数据库sakila
  10. mysql是否有postgreSQL一样的美元包围符