代码如下
- /*
- *
- *
- *
- * 细节: 判断仓库有否有货是否,必须用 while,而不能用 if,作用是让线程醒过来的时候,还要判断是否为空,如果用 if 的话,就不会判断,直接往下走,会导致连续生产或者消费
- * 超过两个线程的时候,用 notifyAll 唤醒,不要用 notify
- *
- *
- */
- class Resource {
- private String name;
- private int id=1;
- private boolean isEmpty = true;
- public synchronized void put(String name) { //生产
- //如果不是空,就 wait()
- while(!isEmpty) {
- try {
- wait();//放弃锁,在这里等,本线程暂停
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- //否则,执行下面代码
- this.name = name+“–“+id++;
- System.out.println(Thread.currentThread().getName()+” 生产者 “+this.name);
- isEmpty = false;
- this.notifyAll();//释放锁,所有 wait 中的线程重新唤醒,开始抢 cpu 执行权
- }
- public synchronized void get() { //消费
- //如果是空的,就 wait()
- while(isEmpty) {
- try {
- wait();//放弃锁,在这里等,本线程暂停
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- //否则,执行下面代码
- System.out.println(Thread.currentThread().getName()+” 消费者 “+this.name);
- isEmpty = true;
- this.notifyAll();//释放锁,所有 wait 中的线程重新唤醒,开始抢 cpu 执行权
- }
- }
- class Producer implements Runnable{
- private Resource res;
- public Producer(Resource res) {
- this.res = res;
- }
- public void run() {
- while(true) {
- res.put(“化肥”);
- }
- }
- }
- class Consumer implements Runnable {
- private Resource res;
- public Consumer(Resource res) {
- this.res = res;
- }
- public void run() {
- while(true) {
- res.get();
- }
- }
- }
- public class ProducerConsumerDemo {
- public static void main(String[] args) {
- Resource r = new Resource();
- Producer producer = new Producer(r);
- Consumer consumer = new Consumer(r);
- Thread t1 = new Thread(producer);
- Thread t2 = new Thread(producer);
- Thread t3 = new Thread(consumer);
- Thread t4 = new Thread(consumer);
- t1.start();
- t2.start();
- t3.start();
- t4.start();
- }
- }
注意两点就可以:一个是判断仓库是否有货,用 while;另一个是,多线程用 notifyAll,不要用 notify