Java多线程生产者消费者问题

一、什么是生产者消费者问题?

   生产者负责生产产品,消费者购买产品,当库存为空的时候,生产者继续生产,消费者购买数量要小于等于库存上限,不能出现,生产一次,消费两次,或者生产了没有消费的情况。

二、代码实例

Producer.java类

/**
 * Created by yuandl on 2016-10-11.
 *
 /**
 * 消费者
 */

public class Producer implements Runnable {
    private Resource resource;

    public Producer(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            resource.destroy();
        }

    }
}

Consumer.java

/**
 * 生产者
 */
public class Consumer implements Runnable {
    private Resource resource;

    public Consumer(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            resource.create();
        }

    }
}

Resource.java

package product;

/**
 * Created by yuandl on 2016-10-11./**
 * 资源
 */
public class Resource {

    private int number = 0;

    private boolean flag = false;

    /**
     * 生产资源
     */
    public synchronized void create() {
        while (flag) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        number++;
        System.out.println(Thread.currentThread().getName() + "生产者------------" + number);
        flag = true;
        notifyAll();
    }

    /**
     * 消费资源
     */
    public synchronized void destroy() {
        while (!flag) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println(Thread.currentThread().getName() + "消费者****" + number);

        flag = false;
        notifyAll();
    }
}

ProducerConsumerTest.java

/**
 * Created by yuandl on 2016-10-11.
 */
public class ProducerConsumerTest {
    public static void main(String args[]) {
        Resource resource = new Resource();
        new Thread(new Consumer(resource)).start();
        new Thread(new Consumer(resource)).start();
        new Thread(new Producer(resource)).start();
        new Thread(new Producer(resource)).start();

    }

}

                                        
运行结果
                                   
这里写图片描述

三、问题研究

  按照示例,生产者消费者交替运行,每次生产后都有对应的消费者,测试类创建实例,如果是生产者先运行,进入run()方法,进入create()方法,flag默认为false,number+1,生产者生产一个产品,flag置为true,同时调用notifyAll()方法,唤醒所有正在等待的线程,接下来如果还是生产者运行呢?这是flag为true,进入while循环,执行wait()方法,接下来如果是消费者运行的话,调用destroy()方法,这时flag为true,消费者购买了一次产品,随即将flag置为false,并唤醒所有正在等待的线程。这就是一次完整的多生产者对应多消费者的问题。

四、疑问

  疑问1:为什么要用while?怎么不用if?
  如果是一个生产者和一个消费者的情况,用if是可以的,但是使用if有局限。一旦触发了if判断条件,所有进入其中的线程都会变成等待的状态,容易造成只有生产,消费者都在等待的情况。
  疑问2:为什么用notifyAll而不是notify?
  直接运行notify会出现”假死”的状态,因为调用notify()方法一次只会唤醒一个优先级最高的线程。那么什么是线程的优先级呢?
  这里写图片描述
  线程会被划分为1到10,10个等级,数字越大优先级就越高,默认优先级是5。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值