Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
线程“thread -0”java.lang.IllegalMonitorStateException中的异常
/*** * Title:生产者* Description:* @author lcs* @date 2018年12月12日* @version 1.0*/
public class Productor implements Runnable{private static String[] goodsType={"iPhone7", "iPhone8", "iPhoneX", "博世冰箱", "格力空调", "吉利房车", "电动汽车", "思科路由器", "华为交换机", "大疆无人机"};private static final int STORE_MAX = 1000;//单例,getProductorprivate static Productor productor=null;public static Productor getProductor(){if(productor == null)productor =new Productor();//创建的时候就使用无参构造方法return productor;}//编写无参构造方法private Productor(){//要给出具体的实现方法,总是增删改,所以用linkedList方法store = new LinkedList();}//库存private List store;//再搞把锁对象private Object lock;public void setLock(Object lock){this.lock=lock;}//此方法为从库存中获取一个商品的最基本操作//此方法只会在消费者线程中调用,因此我们可以在消费者处进行同步//库存store也是private的,消费这个操作不好直接对库存进行操作 //是给Consumer配置的方法,增加是add往最后加,那么消费的时候就remove(0),从头拿//有一个就拿一个,疑问若有类型A的东西,但没有类型b的东西,但是拿b怎么办?public Goods getOneGoods(){Goods g =null;if (store.size()==0) return null;g=store.remove(0);//打印库存剩余产品数量System.out.println("消费一个商品,库存目前剩余:" + store.size());return g;}//一次生产N个产品,N设定为5-10//一批产品,为能够生产的10种中的同一种产品private void produceGoods(){//随机出本次商品的数量int n= (int) (Math.random()*101+50);//随机出商品的种类int type= (int) (Math.random()*10);String gType=goodsType[type];int i;synchronized (lock) {for ( i = 0; i //意思是不可能让一直生产,cpu主频很快,得休息一下啊Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
出现这个问题是没有把判断条件放入到synchronized方法块里面
生产者和消费者两个都是多线程,不管别人怎么样,自己生产,同时也消费
synchronized(this) //锁住当前对象的引用,则任何线程通过当前线程访问到此句,会锁住,直到放开锁,其他线程才能进来。
重写run方法:run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程终止,而CPU再运行其它线程
想想哪里可能有线程冲突:1,生产的时候add,另一个线程消费了remove了,底层不知道,尼玛你到底想干嘛,我操2,一个线程看到还有一个产品,两个线程同时去消费这个产品,产生空指针异常
所以呢,方法前面加synchronized,但是Productor是一个单例对象,这个对象拿来同步,但是Consumer怎么同步呢?
所以,把对生产者库存的这个数据要保护起来,把跟集合有关系的包进来
package com.chinasofti.ProductorConsumer;public class Goods {//当前一共产出了多少个货物public static int count = 0;//生产了产品,name就是public static Goods createOneGoods(String name){count++;return new Goods(count,name);}private Goods(int id, String name) {this.id = id;this.name = name;}private int id;//一个货物对象一个id编号private String name;@Overridepublic String toString() {return "Goods [id=" + id + ", name=" + name + "]";}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
package com.chinasofti.ProductorConsumer;public class Consumer extends Thread{private static int consumedGoods = 0;private Object lock;public Consumer(String name){super(name);}public void setLock(Object lock) {this.lock = lock;}private void consumeGoods(){//一次消费N个商品,从生产商处拿货int n = (int)(Math.random()*2 + 1);//一次消费10-20个商品synchronized (lock) {for(int i=0;i}
package com.chinasofti.ProductorConsumer;public class TestClass {public static void main(String[] args) {Object lock &#61;new Object();//生产者消费者都用一个锁Thread productor &#61;new Thread(Productor.getProductor());Productor.getProductor().setLock(lock);productor.start();try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}//十个顾客for(int i&#61;0;i<10;i&#43;&#43;){Consumer consumer &#61;new Consumer("顾客"&#43;i&#43;1);consumer.setLock(lock);consumer.start();}}
}