生产消费模型——让你明白线程状态

假设你现在变成京东老总,你会遇到一个问题:在仓库容量有限的情况下,控制货物存放,同时将货物送出。如何控制这种情况呢?在java中,我们可以借用生产消费模型来完成。

问题可以简化为:生产者生产货物放在仓库里,而消费者从仓库拿出货物

 

但是我们也会遇到一些问题:效率过低,仓库满空情况的判断

解决思路:利用并发式提高效率,借助线程状态来配合仓库满空情况。

现在正式开始:

1.建立仓库类,成员数据为货物数量。

2.建立生产者线程:

值得去搜索一下线程各个状态!

/**
                 * 线程等待wait,即线程没有操作权,无论cpu有无分配到时间都不会执行
                 * 线程唤醒notify,即将线程唤醒,获取操作权,只要得到cpu时间就可运行
                 * 使用wait,notify之前要获取对象监视器,不然会抛出IllegalMonitorStateException异常
                 * wait()会立刻释放synchronized(obj)中的obj锁,以便其他线程可以执行obj.notify()。
                 * 但是notify()不会立刻立刻释放sycronized(obj)中的obj锁,必须要等notify()所在线程执行完synchronized(obj)块中的所有代码才会释放这把锁。
                 * 之所以用lock也可以释放锁,因为ReentrantLock是基于synchronized而所写的
                 */

public class Producer implements Runnable{
    //得到唯一仓库对象,方便上锁以及wait方法
    private Store store;
    public Producer(Store store){
        this.store = store;
    }
    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            /**
             * 由于并发式操作,为了保证线程安全,需要使用“锁”
             * 但是,必须保证锁和wait作用于同一对象,不然会出现“死锁”现象
             */
            synchronized (store) {
                /**
                 * 线程等待wait,即线程没有操作权,无论cpu有无分配到时间都不会执行
                 * 线程唤醒notify,即将线程唤醒,获取操作权,只要得到cpu时间就可运行
                 * 使用wait,notify之前要获取对象监视器,不然会抛出IllegalMonitorStateException异常
                 * wait()会立刻释放synchronized(obj)中的obj锁,以便其他线程可以执行obj.notify()。
                 * 但是notify()不会立刻立刻释放sycronized(obj)中的obj锁,必须要等notify()所在线程执行完synchronized(obj)块中的所有代码才会释放这把锁。
                 * 之所以用lock也可以释放锁,因为ReentrantLock是基于synchronized而所写的
                 */
                if (store.N >= 20){
                    try {
                        //得知仓库已满状态
                        System.out.println("仓库已满"+Thread.currentThread().getName()+"生产者进入等待状态");
                        store.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else {
                    //如果没有满,则开始生产
                    store.N++;
                    System.out.println(Thread.currentThread().getName() + "线程 正在生产数据...   " + store.N);
                    /**
                     * 开始唤醒生产者,进行生产,给消费者提供数据消费
                     * 同时保证了,生产消费可以一直进行下去。
                     */
                    store.notify();
                }
            }
        }
    }
}

3.建立消费者线程:

思路与生产者线程一致。

4.在仓库内启动线程:

 public void start(){
        Producer producer= new Producer(this);
        new Thread(producer).start();
        new Thread(producer).start();
        new Thread(producer).start();

        Consumer consumer = new Consumer(this);
        new Thread(consumer).start();
        new Thread(consumer).start();

    }
    public static void main(String[] args) {
        Store ss = new Store();
        ss.start();
    }

运行结果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个使用Java语言实现的生产者和消费模型的示例: ``` import java.util.LinkedList; public class ProducerConsumerExample { public static void main(String[] args) { LinkedList<Integer> queue = new LinkedList<>(); int maxSize = 5; Producer producer = new Producer(queue, maxSize); Consumer consumer = new Consumer(queue); Thread producerThread = new Thread(producer, "Producer"); Thread consumerThread = new Thread(consumer, "Consumer"); producerThread.start(); consumerThread.start(); } } class Producer implements Runnable { private LinkedList<Integer> queue; private int maxSize; public Producer(LinkedList<Integer> queue, int maxSize) { this.queue = queue; this.maxSize = maxSize; } @Override public void run() { while (true) { synchronized (queue) { while (queue.size() == maxSize) { try { System.out.println("队列已满,生产者等待消费..."); queue.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } int number = (int) (Math.random() * 100); queue.add(number); System.out.println("生产生产: " + number); queue.notifyAll(); } } } } class Consumer implements Runnable { private LinkedList<Integer> queue; public Consumer(LinkedList<Integer> queue) { this.queue = queue; } @Override public void run() { while (true) { synchronized (queue) { while (queue.isEmpty()) { try { System.out.println("队列为空,消费者等待生产..."); queue.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } int number = queue.removeFirst(); System.out.println("消费消费: " + number); queue.notifyAll(); } } } } ``` 上述代码实现了一个简单的生产者和消费模型,其中使用了一个线程安全的`LinkedList`队列作为生产者和消费者之间的缓冲区。在`Producer`和`Consumer`中,`run()`方法被覆盖并实现了生产消费的逻辑。 在生产线程中,如果队列已满,则生产线程将进入等待状态。当队列不满时,生产线程将生成随机数并将其添加到队列中,并通过调用`notifyAll()`方法通知消费线程可以消费了。在消费线程中,如果队列为空,则消费线程将进入等待状态。当队列不为空时,消费线程将从队列中删除第一个元素,并通过调用`notifyAll()`方法通知生产线程可以继续生产。 这种实现方式使用`synchronized`关键字确保在对队列进行修改时线程安全。此外,生产者和消费线程之间的通信使用了`wait()`和`notifyAll()`方法,以确保生产者和消费者之间的协调。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值