为什么会报java.lang.IllegalMonitorStateException错误
违法的监控状态异常。当某个线程试图等待一个自己并不拥有的对象(O)的监控器或者通知其他线程等待该对象(O)的监控器时,抛出该异常。自己在用wait(),notify()和ArrayList模拟消费者生产者问题时报错。代码如下:
import java.util.ArrayList; /** * @author hetiantian * 模拟生产者生产食物 */ public class Producer implements Runnable { //一次最多只能生产五个,如果到达五个了就需等待消费者把它吃了才能继续生产 private static ArrayList<Food> foods = new ArrayList<>(5); static int id; //事物标记 public Producer(ArrayList<Food> foods) { this.foods = foods; } //模拟生产的过程 public static void productFood() throws InterruptedException { while (true) { Food f = new Food(id++); synchronized (foods) { if (foods.size() >= 5) { f.wait(); //如果大于等于6将被挂起,只有被消费了以后才会继续执行下一步的操作 } else { foods.add(f); System.out.println("生产了:" + f); } } } } @Override public void run() { try { productFood(); } catch (InterruptedException e) { e.printStackTrace(); } } }
报错信息:
生产了:Food[id=1] 生产了:Food[id=2] 生产了:Food[id=3] 生产了:Food[id=4] 消费了:Food[id=4] 消费了:Food[id=3] 消费了:Food[id=2] 消费了:Food[id=1] 消费了:Food[id=0] java.lang.IllegalMonitorStateException
自己原先设计的时候,是food持有锁,但是运行的时候发现,生产者和消费者持有的不是相同的food,这样的话就无法模拟了。后来分析大家持有的是ArrayList这个生产线,因此因对它加锁,而修改的时候只修改了synchronized()里面的持有锁对象,忘记修改等待的对像了,此时food在等待food的锁,而持有锁的是ArrayList,因此就会报错。