Java实现生产者消费者模型

【JAVA】38. Condition条件队列实现生产者 - 消费者模型 在 Java 中,Condition接口是 Java 并发包中的一个重要接口,它为线程提供了一种更灵活的等待/通知机制,与Object类的wait()notify()和方法类似,但功能更强大。Condition实例是由Lock实例创建的,一个Lock可以创建多个Condition实例,每个Condition实例都有自己的等待队列。 阅读详情

Java实现生产者消费者模型问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品。解决生产者/消费者问题的方法可分为两类:(1)采用某种机制保护生产者和消费者之间的同步;(2)在生产者和消费者之间建立一个管道。第一种方式有较高的效率,并且易于实现,代码的可控制性较好,属于常用的模式。第二种管道缓冲区不易控制,被传输数据对象不易于封装等,实用性不强。因此本文只介绍同步机制实现的生产者/消费者问题。

同步问题核心在于:如何保证同一资源被多个线程并发访问时的完整性。常用的同步方法是采用信号或加锁机制,保证资源在任意时刻至多被一个线程访问。Java语言在多线程编程上实现了完全对象化,提供了对同步机制的良好支持。在Java中一共有四种方法支持同步,其中前三个是同步方法,一个是管道方法。

(1)wait() / notify()方法

(2)await() / signal()方法

(3)BlockingQueue阻塞队列方法

(4)PipedInputStream / PipedOutputStream方法

(5)Semaphore方法

一、wait() / notify()方法

wait() / nofity()方法是基类Object的两个方法,也就意味着所有Java类都会拥有这两个方法,这样,我们就可以为任何对象实现同步机制。

wait()方法:当缓冲区已满/空时,生产者/消费者线程停止自己的执行,放弃锁,使自己处于等等状态,让其他线程执行。

notify()方法:当生产者/消费者向缓冲区放入/取出一个产品时,向其他等待的线程发出可执行的通知,同时放弃锁,使自己处于等待状态。

光看文字可能不太好理解,咱来段代码就明白了:

<span style="font-size:18px;"><span style="font-size:18px;">package com.ft.com.nextxteam.test;

import java.util.LinkedList;

/**
 * 使用wait/notify处理消费者问题
 * Created by drjr on 16-9-19.
 */
public class TestProductConm {


    public static class Storage {

        // 仓库最大存储量
        private final int MAX_SIZE = 100;

        // 仓库存储的载体
        private LinkedList<Object> list = new LinkedList<Object>();

        // 生产num个产品
        public void produce(int num) {
            // 同步代码段
            synchronized (list) {
                // 如果仓库剩余容量不足
                while (list.size() + num > MAX_SIZE) {
                    System.out.println("【要生产的产品数量】:" + num + "/t【库存量】:"
                            + list.size() + "/t暂时不能执行生产任务!");
                    try {
                        // 由于条件不满足,生产阻塞
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                // 生产条件满足情况下,生产num个产品
                for (int i = 1; i <= num; ++i) {
                    list.add(new Object());
                }

                System.out.println("【已经生产产品数】:" + num + "/t【现仓储量为】:" + list.size());

                list.notifyAll();
            }
        }

        // 消费num个产品
        public void consume(int num) {
            // 同步代码段
            synchronized (list) {
                // 如果仓库存储量不足
                while (list.size() < num) {
                    System.out.println("【要消费的产品数量】:" + num + "/t【库存量】:"
                            + list.size() + "/t暂时不能执行生产任务!");
                    try {
                        // 由于条件不满足,消费阻塞
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                // 消费条件满足情况下,消费num个产品
                for (int i = 1; i <= num; ++i) {
                    list.remove();
                }

                System.out.println("【已经消费产品数】:" + num + "/t【现仓储量为】:" + list.size());

                list.notifyAll();
            }
        }

        // get/set方法
        public LinkedList<Object> getList() {
            return list;
        }

        public void setList(LinkedList<Object> list) {
            this.list = list;
        }

        public int getMAX_SIZE() {
            return MAX_SIZE;
        }
    }


    public static class Producer extends Thread {
        // 每次生产的产品数量
        private int num;

        // 所在放置的仓库
        private Storage storage;

        // 构造函数,设置仓库
        public Producer(Storage storage) {
            this.storage = storage;
        }

        // 线程run函数
        public void run() {
            produce(num);
        }

        // 调用仓库Storage的生产函数
        public void produce(int num) {
            storage.produce(num);
        }

        // get/set方法
        public int getNum() {
            return num;
        }

        public void setNum(int num) {
            this.num = num;
        }

        public Storage getStorage() {
            return storage;
        }

        public void setStorage(Storage storage) {
            this.storage = storage;
        }
    }


    public static class Consumer extends Thread {
        // 每次消费的产品数量
        private int num;

        // 所在放置的仓库
        private Storage storage;

        // 构造函数,设置仓库
        public Consumer(Storage storage) {
            this.storage = storage;
        }

        // 线程run函数
        public void run() {
            consume(num);
        }

        // 调用仓库Storage的生产函数
        public void consume(int num) {
            storage.consume(num);
        }

        // get/set方法
        public int getNum() {
            return num;
        }

        public void setNum(int num) {
            this.num = num;
        }

        public Storage getStorage() {
            return storage;
        }

        public void setStorage(Storage storage) {
            this.storage = storage;
        }
    }

    public static void main(String[] args) {
        // 仓库对象
        Storage storage = new Storage();

        // 生产者对象
        Producer p1 = new Producer(storage);
        Producer p2 = new Producer(storage);
        Producer p3 = new Producer(storage);
        Producer p4 = new Producer(storage);
        Producer p5 = new Producer(storage);
        Producer p6 = new Producer(storage);
        Producer p7 = new Producer(storage);

        // 消费者对象
        Consumer c1 = new Consumer(storage);
        Consumer c2 = new Consumer(storage);
        Consumer c3 = new Consumer(storage);

        // 设置生产者产品生产数量
        p1.setNum(10);
        p2.setNum(10);
        p3.setNum(10);
        p4.setNum(10);
        p5.setNum(10);
        p6.setNum(10);
        p7.setNum(80);

        // 设置消费者产品消费数量
        c1.setNum(50);
        c2.setNum(20);
        c3.setNum(30);

        // 线程开始执行
        c1.start();
        c2.start();
        c3.start();
        p1.start();
        p2.start();
        p3.start();
        p4.start();
        p5.start();
        p6.start();
        p7.start();
    }
}</span></span>


二、await() / signal()方法

在JDK5.0之后,Java提供了更加健壮的线程处理机制,包括同步、锁定、线程池等,它们可以实现更细粒度的线程控制。await()和signal()就是其中用来做同步的两种方法,它们的功能基本上和wait() / nofity()相同,完全可以取代它们,但是它们和新引入的锁定机制Lock直接挂钩,具有更大的灵活性。通过在Lock对象上调用newCondition()方法,将条件变量和一个锁对象进行绑定,进而控制并发程序访问竞争资源的安全。下面来看代码:

<span style="font-size:18px;"><span style="font-size:18px;">package com.ft.com.nextxteam.test;

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 使用wait/notify处理消费者问题
 * Created by drjr on 16-9-19.
 */
public class TestProductConm {


    public static class Storage {

        // 仓库最大存储量
        private final int MAX_SIZE = 100;

        // 仓库存储的载体
        private LinkedList<Object> list = new LinkedList<Object>();


        // 锁
        private final Lock lock = new ReentrantLock();

        // 仓库满的条件变量
        private final Condition full = lock.newCondition();

        // 仓库空的条件变量
        private final Condition empty = lock.newCondition();


        // 生产num个产品
        public void produce(int num) {
            ///获得锁
            lock.lock();
            // 如果仓库剩余容量不足
            while (list.size() + num > MAX_SIZE) {
                System.out.println("【要生产的产品数量】:" + num + "/t【库存量】:"
                        + list.size() + "/t暂时不能执行生产任务!");
                try {
                    // 由于条件不满足,生产阻塞
                    full.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            // 生产条件满足情况下,生产num个产品
            for (int i = 1; i <= num; ++i) {
                list.add(new Object());
            }

            System.out.println("【已经生产产品数】:" + num + "/t【现仓储量为】:" + list.size());

            // 唤醒其他所有线程
            full.signalAll();
            empty.signalAll();
            // 释放锁
            lock.unlock();
        }

        // 消费num个产品
        public void consume(int num) {
            //获得锁
            lock.lock();
            // 如果仓库存储量不足
            while (list.size() < num) {
                System.out.println("【要消费的产品数量】:" + num + "/t【库存量】:"
                        + list.size() + "/t暂时不能执行生产任务!");
                try {
                    // 由于条件不满足,消费阻塞
                    empty.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            // 消费条件满足情况下,消费num个产品
            for (int i = 1; i <= num; ++i) {
                list.remove();
            }

            System.out.println("【已经消费产品数】:" + num + "/t【现仓储量为】:" + list.size());
            // 唤醒其他所有线程
            full.signalAll();
            empty.signalAll();
            // 释放锁
            lock.unlock();
        }

        // get/set方法
        public LinkedList<Object> getList() {
            return list;
        }

        public void setList(LinkedList<Object> list) {
            this.list = list;
        }

        public int getMAX_SIZE() {
            return MAX_SIZE;
        }
    }


    public static class Producer extends Thread {
        // 每次生产的产品数量
        private int num;

        // 所在放置的仓库
        private Storage storage;

        // 构造函数,设置仓库
        public Producer(Storage storage) {
            this.storage = storage;
        }

        // 线程run函数
        public void run() {
            produce(num);
        }

        // 调用仓库Storage的生产函数
        public void produce(int num) {
            storage.produce(num);
        }

        // get/set方法
        public int getNum() {
            return num;
        }

        public void setNum(int num) {
            this.num = num;
        }

        public Storage getStorage() {
            return storage;
        }

        public void setStorage(Storage storage) {
            this.storage = storage;
        }
    }


    public static class Consumer extends Thread {
        // 每次消费的产品数量
        private int num;

        // 所在放置的仓库
        private Storage storage;

        // 构造函数,设置仓库
        public Consumer(Storage storage) {
            this.storage = storage;
        }

        // 线程run函数
        public void run() {
            consume(num);
        }

        // 调用仓库Storage的生产函数
        public void consume(int num) {
            storage.consume(num);
        }

        // get/set方法
        public int getNum() {
            return num;
        }

        public void setNum(int num) {
            this.num = num;
        }

        public Storage getStorage() {
            return storage;
        }

        public void setStorage(Storage storage) {
            this.storage = storage;
        }
    }

    public static void main(String[] args) {
        // 仓库对象
        Storage storage = new Storage();

        // 生产者对象
        Producer p1 = new Producer(storage);
        Producer p2 = new Producer(storage);
        Producer p3 = new Producer(storage);
        Producer p4 = new Producer(storage);
        Producer p5 = new Producer(storage);
        Producer p6 = new Producer(storage);
        Producer p7 = new Producer(storage);

        // 消费者对象
        Consumer c1 = new Consumer(storage);
        Consumer c2 = new Consumer(storage);
        Consumer c3 = new Consumer(storage);

        // 设置生产者产品生产数量
        p1.setNum(10);
        p2.setNum(10);
        p3.setNum(10);
        p4.setNum(10);
        p5.setNum(10);
        p6.setNum(10);
        p7.setNum(80);

        // 设置消费者产品消费数量
        c1.setNum(50);
        c2.setNum(20);
        c3.setNum(30);

        // 线程开始执行
        c1.start();
        c2.start();
        c3.start();
        p1.start();
        p2.start();
        p3.start();
        p4.start();
        p5.start();
        p6.start();
        p7.start();
    }
}</span></span>

三、BlockingQueue阻塞队列方法

BlockingQueue是JDK5.0的新增内容,它是一个已经在内部实现了同步的队列,实现方式采用的是我们第2种await() / signal()方法。它可以在生成对象时指定容量大小。它用于阻塞操作的是put()和take()方法。

put()方法:类似于我们上面的生产者线程,容量达到最大时,自动阻塞。

take()方法:类似于我们上面的消费者线程,容量为0时,自动阻塞。

关于BlockingQueue的内容网上有很多,大家可以自己搜,我在这不多介绍。下面直接看代码,跟以往一样,我们只需要更改仓库类Storage的代码即可:

<span style="font-size:18px;"><span style="font-size:18px;">package com.ft.com.nextxteam.test;

import java.util.LinkedList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 使用wait/notify处理消费者问题
 * Created by drjr on 16-9-19.
 */
public class TestProductConm {


    public static class Storage {

        // 仓库最大存储量
        private final int MAX_SIZE = 100;

        // 仓库存储的载体
        private LinkedBlockingQueue<Object> list = new LinkedBlockingQueue<Object>();


        // 生产num个产品
        public void produce(int num) {
            // 如果仓库剩余容量不足
            while (list.size() + num > MAX_SIZE) {
                System.out.println("【要生产的产品数量】:" + num + "/t【库存量】:"
                        + list.size() + "/t暂时不能执行生产任务!");
            }

            // 生产条件满足情况下,生产num个产品
            for (int i = 1; i <= num; ++i) {
                try {
                    list.put(new Object());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            System.out.println("【已经生产产品数】:" + num + "/t【现仓储量为】:" + list.size());
        }

        // 消费num个产品
        public void consume(int num) {
            // 如果仓库存储量不足
            while (list.size() < num) {
                System.out.println("【要消费的产品数量】:" + num + "/t【库存量】:"
                        + list.size() + "/t暂时不能执行生产任务!");
            }

            // 消费条件满足情况下,消费num个产品
            for (int i = 1; i <= num; ++i) {
                try {
                    list.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            System.out.println("【已经消费产品数】:" + num + "/t【现仓储量为】:" + list.size());
        }

        // get/set方法
        public LinkedBlockingQueue<Object> getList() {
            return list;
        }

        public void setList(LinkedBlockingQueue<Object> list) {
            this.list = list;
        }

        public int getMAX_SIZE() {
            return MAX_SIZE;
        }
    }


    public static class Producer extends Thread {
        // 每次生产的产品数量
        private int num;

        // 所在放置的仓库
        private Storage storage;

        // 构造函数,设置仓库
        public Producer(Storage storage) {
            this.storage = storage;
        }

        // 线程run函数
        public void run() {
            produce(num);
        }

        // 调用仓库Storage的生产函数
        public void produce(int num) {
            storage.produce(num);
        }

        // get/set方法
        public int getNum() {
            return num;
        }

        public void setNum(int num) {
            this.num = num;
        }

        public Storage getStorage() {
            return storage;
        }

        public void setStorage(Storage storage) {
            this.storage = storage;
        }
    }


    public static class Consumer extends Thread {
        // 每次消费的产品数量
        private int num;

        // 所在放置的仓库
        private Storage storage;

        // 构造函数,设置仓库
        public Consumer(Storage storage) {
            this.storage = storage;
        }

        // 线程run函数
        public void run() {
            consume(num);
        }

        // 调用仓库Storage的生产函数
        public void consume(int num) {
            storage.consume(num);
        }

        // get/set方法
        public int getNum() {
            return num;
        }

        public void setNum(int num) {
            this.num = num;
        }

        public Storage getStorage() {
            return storage;
        }

        public void setStorage(Storage storage) {
            this.storage = storage;
        }
    }

    public static void main(String[] args) {
        // 仓库对象
        Storage storage = new Storage();

        // 生产者对象
        Producer p1 = new Producer(storage);
        Producer p2 = new Producer(storage);
        Producer p3 = new Producer(storage);
        Producer p4 = new Producer(storage);
        Producer p5 = new Producer(storage);
        Producer p6 = new Producer(storage);
        Producer p7 = new Producer(storage);

        // 消费者对象
        Consumer c1 = new Consumer(storage);
        Consumer c2 = new Consumer(storage);
        Consumer c3 = new Consumer(storage);

        // 设置生产者产品生产数量
        p1.setNum(10);
        p2.setNum(10);
        p3.setNum(10);
        p4.setNum(10);
        p5.setNum(10);
        p6.setNum(10);
        p7.setNum(80);

        // 设置消费者产品消费数量
        c1.setNum(50);
        c2.setNum(20);
        c3.setNum(30);

        // 线程开始执行
        c1.start();
        c2.start();
        c3.start();
        p1.start();
        p2.start();
        p3.start();
        p4.start();
        p5.start();
        p6.start();
        p7.start();
    }
}</span></span>

四、Semaphore方法

信号量(Semaphore)维护了一个许可集。在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。 
Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。

 注意,调用 acquire() 时无法保持同步锁,因为这会阻止将项返回到池中。信号量封装所需的同步,以限制对池的访问,这同维持该池本身一致性所需的同步是分开的。同步令牌(notFull.acquire())必须在互斥令牌(mutex.acquire())前面获得,如果先得到互斥锁再发生等待,会造成死锁。

五、PipedInputStream / PipedOutputStream方法

  这个类位于java.io包中,是解决同步问题的最简单的办法,一个线程将数据写入管道,另一个线程从管道读取数据,这样便构成了一种生产者/消费者的缓冲区编程模式。PipedInputStream/PipedOutputStream只能用于多线程模式,用于单线程下可能会引发死锁。 一般不使用,因为缓冲区不易控制、数据不易封装和传输。



半桥LLC谐振变换器及同步整流MATLAB仿真(一) LLC工作原理详细解析,工作过程详细拆解 阅读详情

相关推荐

# ubuntu 系统使用 yum命令报错 There are no enabled repos.Run “yum repolist all“ to see the repos you have...

# ubuntu 系统使用 yum命令报错 There are no enabled repos.Run "yum repolist all" to see the repos you have.You can enable repos with yum-config-manager --enable

段子手168的博客 6678

【Java】生产者消费者模式的实现

前言生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据。阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队列就是用来给生产者和消费者解耦的。wait/notify方法首先,我们搞清楚Thread.sleep()方法和Object.wait()、Object.notify()方法的区别。根据这篇文章java

Mlib 4万+

平衡小车动力学建模

两轮自平衡小车由车体和双轮两部分组成,可以看成一个移动的倒立摆,分别对车轮和车体进行力学分析,建立动力学模型,最后,通过对两者的分析给出系统的状态空间表达式。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kjiPEUVJ-1679470559950)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230322110521545.png)]

qq_23096319的博客 9051

由生产者/消费者问题看JAVA多线程

        生产者消费者问题是研究多线程程序时绕不开的问题,它的描述是有一块生产者和消费者共享的有界缓冲区,生产者往缓冲区放入产品,消费者从缓冲区取走产品,这个过程可以无休止的执行,不能因缓冲区满生产者放不进产品而终止,也不能因缓冲区空消费者无产品可取而终止。       解决生产者消费者问题的方法有两种,一种是采用某种机制保持生产者和消费者之间的同步,一种是在生产者和消费者之间建立一

coutcin的专栏 1万+

VCS多lib编译实战:如何高效处理Verilog模块重命名与分开编译

本文深入探讨了在复杂SoC设计中,如何利用VCS工具实现多库编译,以高效处理Verilog模块重命名与分开编译的工程难题。通过解析synopsys_sim.setup配置、Config映射机制,并提供完整的自动化脚本实战指南,帮助工程师构建健壮、可维护的编译环境,从而显著提升大型项目的编译效率和代码管理灵活性。

weixin_29169505的博客 355

10BASE-T1S协议中的PLCA机制:实现无碰撞网络传输的关键

本文深入解析了10BASE-T1S协议中的PLCA(物理层冲突避免)机制。作为IEEE 802.3cg标准的关键部分,PLCA通过循环调度与机会传递,从根源上避免了网络碰撞,为工业与汽车等场景提供了确定性的低延迟传输保障,是实现可靠实时通信的核心技术。

weixin_29250403的博客 209

惊!用Java实现生产者消费者问题能这么简单?

Java简单实现生产者消费者问题 单个消费者 今天结束了多线程的学习,使用wait和notify来进行线程间的通信以此实现简易的生产者消费者问题; 首先来看什么是生产者消费者问题: 所谓生产者-消费者问题,实际上主要是包含了两类线程,一种是生产者线程用于生产数据,另一种是消费者线程用于消费数据,为了解耦生产者和消费者的关系,通常会采用共享的数据区域,就像是一个仓库,生产者生产数据之后直接放置在共享数据区中,并不需要关心消费者的行为;而消费者只需要从共享数据区中去获取数据,就不再需要关心生产者的行为。 因

wcyyyyyyy的博客 194

从Canny到深度学习:边缘检测指标进化史(含ODS/OIS/AP的数学推导)

本文系统梳理了边缘检测评估指标的演进历程,从经典的Canny算子到深度学习时代,重点解析了ODS、OIS和AP三大核心指标的设计哲学与数学推导。文章深入探讨了基于PR曲线的评估体系,揭示了不同指标(如ODS与OIS)在阈值优化上的差异,并分析了AP指标在边缘检测任务中的优势与局限,为算法研究和模型评估提供了实用指南。

b9c0d的博客 197

生产者消费者模型

将上述场景例比到我们实际的软件开发过程中,经常会见到这样一幕:代码的某个模块负责生产数据(供货商),而生产出来的数据却不得不交给另一模块(消费者)来对其进行处理,在这之间我们必须要有一个类似上述超市的东西来存储数据(超市),这就抽象除了我们的生产者/消费者模型。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

kalvin_y_liu的博客 6940

搭建ROS小车真的难吗?

搭建ROS小车真的难吗?不难 1.引言 本着为大家谋福利的心态,根据自己以往的开发经验,打算写一个从零开始制作一个可以实现地图构建和导航的ROS小车。目前某宝上面有很多现成产品,但是我个人认为,一个好的移动机器人开发工程师,应该对机器人的整个流程都能具备维护的能力,然后再深入研究其中一个方向即可。看到网上很少有整个系列的开发教程,看到同学们大多东拼西凑,浪费了不少时间。我就想着利用空余时间,将我本人的开发过程输出给大家。有基础理论、有实际工程代码、有丰富的学习资料,尽最大努力帮大家进入移动机器人的大门。 国

「小白学移动机器人」一个专注分享移动机器人相关知识的公众号! 1万+

原理之(〇)3D Gaussian Splatting 数学原理与推导

3D Gaussian Splatting源于EWA的理论基础,本文重点从EWA模型出发,详细推导3D GS中的数学原理,加深对鱼眼相机畸变场景下的理解。

scott198512的博客 4156

(四)生产者消费者模式

(一)生产者消费者模式原理: 在一个系统中,存在生产者和消费者两种角色,他们通过内存缓冲区进行通信,生产者生产消费者需要的资料,消费者把资料做成产品。生产消费者模式如下图: (二)代码实现 生产者是一堆线程,消费者是另一堆线程,内存缓冲区可以使用List数组队列,数据类型只需要定义一个简单的类就好。最关键就是内存缓冲区为空的时候消费者必须等待,而内存缓冲区满的时候,生产者必须等待。其他时候可以是个动态平衡:   首先设置Market类: 其中变量有:Max(仓库最大值),List(用于存放数据) 方法有

roothahh的博客 9787

[23]-->变长SPI接口

然而,FPGA技术复杂,学习门槛较高,许多人(初学者或学生)在学习过程中面临诸多挑战。(1)模式0:SCK串行时钟线空闲是为低电平,数据在SCK时钟的上升沿被采样,数据在SCK时钟的下降沿切换,CPOL= 0,CPHA=0;(2)模式1:SCK串行时钟线空闲是为低电平,数据在SCK时钟的下降沿被采样,数据在SCK时钟的上升沿切换,CPOL= 0,CPHA=1;(3)模式3:SCK串行时钟线空闲是为高电平,数据在SCK时钟的上升沿被采样,数据在SCK时钟的下降沿切换,CPOL= 1,CPHA=1;

m0_46498597的博客 177

java实现生产者消费者模型

生产者消费者模型 生产者消费者模型,是通过一个容器来解决生产者和消费者的强耦合问题。通俗的讲,就是生产者在不断的生产,消费者也在不断的消费,可是消费者消费的产品是生产者生产的,这就必然存在一个中间容器,我们可以把这个容器想象成是一个货架,当货架空的时候,生产者要生产产品,此时消费者在等待生产者往货架上生产产品,而当货架满的时候,消费者可以从货架上拿走商品,生产者此时等待货架的空位,这样不断的循环。那么在这个过程中,生产者和消费者是不直接接触的,所谓的‘货架’其实就是一个阻塞队列,生产者生产的产品不直接给消费

KEVIN_WANG333的博客 267

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

生产者-消费者模型Java代码实现

转载请注明出处 作者:@LSZJXin 由于本人水平有限,如有不正确的地方欢迎留言指出,谢谢! 考查Java的并发编程时,手写”生产者-消费者模型”是一个经典问题。本文给出一种相对比较简单容易理解、容易实现的java代码实现这一模型。 步骤: 1. 创建一个实体类(本例为WoTou) 2. 创建一个”容器” 3. 创建生产者线程类 4. 创建消费者线程类 5. m...

ZJXin 1987

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

java生产者消费者流程图_Java 生产者消费者模型的三种实现过程

生产者一边在生产,消费者一边消耗。当库存满的时候生产者暂停生产,直到有空位;当库存空的时候消费者暂停消费,直到有产品。关键点:生产者和消费者都是在不断生产和消费的,是同时并发的,不应该等满了再消费 / 空了再生产。前提条件是生产速度和消费速度不同。设计方法:生产者和消费者分别使用一个线程模拟。将其抽象分别继承Runnable接口,生产和消费的行为放在Runnable的run()方法中.控制生产和消...

weixin_33404792的博客 2266

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Java实现生产者与消费者模型

文章目录1. wait与notify方法2. 单线程版生产与消费者模型3. 完备的生产与消费者模型⭐ 1. wait与notify方法 这两个方法实现线程间同步(通信); 调用wait()和notify()方法都需要先获取到该对象的Monitor锁,即调用这两个方法必须包含在synchronized代码块中; 每一个对象都有两个队列: 黄色部分正是证明了: 在线程被notify方法唤醒后,并不会...

eternal_yy 787

Java生产者消费者模型的五种实现方式

转自:https://juejin.im/entry/596343686fb9a06bbd6f888c   前言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,生产者往存储空间中添加产品,消费者从存储空间中取走产品,当存储空间为空时,消费者阻塞,当存储空间满时,生产者阻塞。现在用四种方式来实现生产者消费者模型 wait()和notify()方法的...

wowwilliam0的博客 2万+

Java实现简易生产者消费者模型

生产者消费者模型是一种多线程设计模式,用于解决生产者线程和消费者线程之间的协调问题。在生产者消费者模型中,生产者线程生成数据并将其加入队列,而消费者线程从队列中获取数据并进行消费。在生产者和消费者之间存在一个共享的缓冲区,它作为生产者和消费者之间的中间存储点,用于协调生产者和消费者的工作。当生产者线程生成的数据太多时,它将被阻塞,直到消费者线程消费了一些数据,使队列不再满。当队列不满时,生产者线程才开始生产数据。反之,当队列为空时,消费者线程将阻塞,直到生产者线程生成了数据,消费者线程执行消费。

nothing8727的博客 472

Java基于Queue队列实现生产者消费者模型

测试用生产者模型: package domain; import java.util.Queue; /** * 生产者模型 * * @author WanAkiko * */ public class Productor implements Runnable { private Queue<String> queue; // 生产队列 private Integer maxTask; // 最大产量 int i = 1; // 生产计数 public Produc

WanAkiko. 598

Java实现生产者——消费者模型

对多线程同步问题一直了解不是很深刻,找了生产者消费者模型来试验了一下。不知道正确与否,初步实验了一下好像是正确的,如有错误请指正。 生产者——消费者模型是这样的: 有M个生产者不断的想生产线上放置产品。而有N个消费者从生产线上将产品拿出来。实现这一过程。 代码如下所示: package concurrency; import java.util.Random; import

Solidfish的专栏 1962

生产者消费者模型java实现

做题的时候遇到了生产者消费者问题,这个问题可以说是线程学习的经典题目了,就忍不住研究了一波。它描述是有一块缓冲区(队列实现)作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品。在Java中这个数组线程阻塞的问题,多个用户同时发送多个请求,怎么保证不发生线程死锁,是我们要考虑的问题。 生产者消费者模式说明: 1.生产者只在仓库未满时进行生产,仓库满时生产者进程被阻塞; 2.消费者...

Fighting的博客 1万+

生产者消费者模型-Java实现

Java实现生产者消费者模型 class Clerk { private static int productNumber = 0;//商品的数量 private static final int MAX = 20; //最多可以有20个商品 public synchronized void addProduct() { try { Thread.sleep(1000); //延时,让效果更加明显 } catch (E

qq_30634979的博客 184

Java 生产者消费者模型的三种实现过程

Java 生产者消费者模型的三种实现过程 生产者一边在生产,消费者一边消耗。当库存满的时候生产者暂停生产,直到有空位;当库存空的时候消费者暂停消费,直到有产品。 关键点: 生产者和消费者都是在不断生产和消费的,是同时并发的,不应该等满了再消费 / 空了再生产。 前提条件是生产速度和消费速度不同。 设计方法: 生产者和消费者分别使用一个线程模拟。将其抽象分别继承Runnable接口,生产和消费的行为放在Runnable的run()方法中. 控制生产和消费的速度不同。可以使每次生产 / 每次消费

多回头看一看 392
上一篇: ZooKeeper常用指令集
下一篇: JAVA8新特性
NextX工作室
博客等级 码龄18年 21粉丝 21原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值