下面这段代码,让我明白了wait()等待对象锁和synchronized等待对象锁的区别, wait()等待时,线程是在阻塞状态, 所以需要notify或者notifyAll唤醒使线程状态变为就绪状态才能继续竞争对象锁, 而synchronized等待时, 线程本身就在就绪状态, 所以线程可以直接竞争对象锁(线程可能一直在循环查询对象锁是否可用)。
public class Test {
public static void main(String[] args) {
Godown godown = new Godown(0);
Consumer c1 = new Consumer(10, godown);
// Consumer c2 = new Consumer(20, godown);
// Consumer c3 = new Consumer(30, godown);
Producer p1 = new Producer(10, godown);
// Producer p2 = new Producer(10, godown);
// Producer p3 = new Producer(10, godown);
// Producer p4 = new Producer(10, godown);
// Producer p5 = new Producer(10, godown);
// Producer p6 = new Producer(10, godown);
// Producer p7 = new Producer(80, godown);
c1.start();
// c2.start();
// c3.start();
p1.start();
// p2.start();
// p3.start();
// p4.start();
// p5.start();
// p6.start();
// p7.start();
}
}
/**
* 仓库
*/
class Godown {
public static final int max_size = 100; //最大库存量
public int curnum; //当前库存量
Godown() {
}
Godown(int curnum) {
this.curnum = curnum;
}
/**
* 生产指定数量的产品
*
* @param neednum
*/
public synchronized void produce(int neednum) {
System.out.println("进入生产");
//测试是否需要生产
while (neednum + curnum > max_size) {
System.out.println("要生产的产品数量" + neednum + "超过剩余库存量" + (max_size - curnum) + ",暂时不能执行生产任务!");
try {
//当前的生产线程等待
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//满足生产条件,则进行生产,这里简单的更改当前库存量
curnum += neednum;
System.out.println("已经生产了" + neednum + "个产品,现仓储量为" + curnum);
//唤醒在此对象监视器上等待的所有线程
notifyAll();
}
/**
* 消费指定数量的产品
*
* @param neednum
*/
public synchronized void consume(int neednum) {
System.out.println("进入消费");
//测试是否可消费
while (curnum < neednum) {
System.out.println("正在消费");
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
//当前的生产线程等待
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//满足消费条件,则进行消费,这里简单的更改当前库存量
curnum -= neednum;
System.out.println("已经消费了" + neednum + "个产品,现仓储量为" + curnum);
//唤醒在此对象监视器上等待的所有线程
notifyAll();
}
}
/**
* 生产者
*/
class Producer extends Thread {
private int neednum; //生产产品的数量
private Godown godown; //仓库
Producer(int neednum, Godown godown) {
this.neednum = neednum;
this.godown = godown;
}
public void run() {
//生产指定数量的产品
godown.produce(neednum);
}
}
/**
* 消费者
*/
class Consumer extends Thread {
private int neednum; //生产产品的数量
private Godown godown; //仓库
Consumer(int neednum, Godown godown) {
this.neednum = neednum;
this.godown = godown;
}
public void run() {
//消费指定数量的产品
godown.consume(neednum);
}