生产者消费者模式描述的是协调与协作关系。比如一个人正在准备食物(生产者),而另一个人正在吃(消费者),他们使用一个共用 的桌子用于放置盘子和取走盘子,生产者准备食物,如果桌子上已经满了就等待,消费者(那个吃的)如果桌子空了的话就等待

采用生产者消费者模式可以做到异步,解耦的目的。

public class Produce implements Runnable {

    public Object lock;
public LinkedList<String> list; private volatile boolean isRunning = true; private static AtomicInteger count = new AtomicInteger(); public Produce(Object object, LinkedList<String> list) {
this.lock = object;
this.list = list;
} @Override
public void run() {
try {
while (isRunning) {
Thread.sleep();
synchronized (lock) {
while (list.size() >= ) {
System.out.println(Thread.currentThread().getName() + " 正在等待 ");
lock.wait();
}
String value = "data:"+count.getAndIncrement();
list.offerLast(value);
System.out.println(Thread.currentThread().getName() + " 生产数据 "+ value);
lock.notifyAll();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} } public void stop() {
isRunning = false;
}
}
public class Consumer implements Runnable {

    private volatile boolean isRunning = true;

    public Object lock;

    public LinkedList<String> list;// 用list存放生产之后的数据,最大容量为1

    public Consumer(Object object, LinkedList<String> list ) {
this.lock = object;
this.list = list;
} @Override
public void run() {
try {
while (isRunning) {
synchronized (lock) {
while (list.isEmpty()) {
System.out.println(Thread.currentThread().getName() + " 正在等待");
lock.wait();
}
String value = list.pollFirst();
System.out.println(Thread.currentThread().getName() + " 消费数据 >>"+ value);
lock.notifyAll();//
}
Thread.sleep();
}
} catch (Exception e) {
// TODO: handle exception
}
} public void stop() {
isRunning = false;
}
}
public class Client {

    public static void main(String[] args) {

        Object lock = new Object();
LinkedList<String> list = new LinkedList<String>(); IntStream.range(, ).forEach(i -> new Thread(new Produce(lock, list), "【生产者" + i + "】").start()); IntStream.range(, ).forEach(i -> new Thread(new Consumer(lock, list), "【消费者" + i + "】").start());
} }

多生产者多消费者(第一种方式),基于synchronized,wait,notifyAll的更多相关文章

  1. UserView--第二种方式(避免第一种方式Set饱和),基于Spark算子的java代码实现

      UserView--第二种方式(避免第一种方式Set饱和),基于Spark算子的java代码实现   测试数据 java代码 package com.hzf.spark.study; import ...

  2. SpringBoot集成Mybatis实现多表查询的两种方式(基于xml)

     下面将在用户和账户进行一对一查询的基础上进行介绍SpringBoot集成Mybatis实现多表查询的基于xml的两种方式.   首先我们先创建两个数据库表,分别是user用户表和account账户表 ...

  3. Unity 人物跟谁手指的移动(第一种方式)

    长夜漫漫无心睡眠,敲敲代码,越敲越来劲! 我发现好多小朋友都在玩熊出没之xxxx这个游戏,居然打了一下午都没玩通第2关,我把测试也叫来陪我一起玩! 结果他也打不通,我再去叫策划,他也没打过,我去叫主管 ...

  4. 创建多线程的第一种方式——创建Thread子类和重写run方法

    创建多线程的第一种方式——创建Thread子类和重写run方法: 第二种方式——实现Runnable接口,实现类传参给父类Thread类构造方法创建线程: 第一种方式创建Thread子类和重写run方 ...

  5. Struts2框架的数据封装一之属性封装(属性封装的第一种方式:对参数进行封装)

    request带着参数来,aciton对其进行处理.在学习action之前,使用的是servlet对request进行处理.request请求时会带有参数,所以我们要对这些参数进行封装. 1. 为什么 ...

  6. Spring整合Struts2框架的第一种方式(Action由Struts2框架来创建)。在我的上一篇博文中介绍的通过web工厂的方式获取servcie的方法因为太麻烦,所以开发的时候不会使用。

    1. spring整合struts的基本操作见我的上一篇博文:https://www.cnblogs.com/wyhluckdog/p/10140588.html,这里面将spring与struts2 ...

  7. 创建多线程程序的第一种方式_创建Thread类的子类

    创建多线程程序的第一种方式:创建Thread类的子类java.lang.Thread类:是描述线程的类,我们想要实现多线程程序,就必须继承Thread类 实现步骤: 1.创建一个Thread类的子类 ...

  8. throws关键字_异常处理的第一种方式(交给别人处理)和try_catch_异常处理的第二种方式(自己处理)

    throws关键字:异常处理的第一种方式,交给别人处理 作用: 当方法内部抛出异常对象的时候,那么我们就必须处理这个异常对象 可以使用throws关键字处理异常对象, 会把异常对象声明抛出给方法的调用 ...

  9. 五 Mybatis一对一关联查询的两种方式(基于resultType&基于resultMap)

    关联查询: 一个用户对应多个订单,一个订单只有一个用户 订单关联用户:两种方式 一:基于resultTYpe,一个与表关系一样的pojo实现 主表订单,从表用户 首先要有一个与关联查询表关系一样的po ...

  10. 主线程和创建多线程程序的第一种方式_创建Thread类的子类

    /** * 主线程:执行主方法的线程(main) * 单线程程序:在java程序中只有一个线程 * 执行从main方法开始,从上倒下依次执行 */ public class Demo01MainThr ...

随机推荐

  1. YII框架的行为

    一.什么是行为 行为,也称为 mixins,可以无须改变类继承关系即可增强一个已有的类的功能. 当一个对象或类被注入某些行为后,这个对象可以像访问自己定义的方法和属性一样访问注入进来的方法和属性. 二 ...

  2. mac Understand 安装破解

    下载:链接:https://pan.baidu.com/s/1UvxgFnjv9pRVJmZO-J2OrQ  密码:nyd4 启动后,开始激活,点击enter License code 点击“use ...

  3. Java 操作Redis封装RedisTemplate工具类

    package com.example.redisdistlock.util; import org.springframework.beans.factory.annotation.Autowire ...

  4. 中山纪中集训Day1测试(摸鱼)

    AT3 粉刷匠 Description 赫克托是一个魁梧的粉刷匠,而且非常喜欢思考= = 现在,神庙里有N根排列成一直线的石柱,从1到N标号,长老要求用油漆将这些石柱重新粉刷一遍.赫克托有K桶颜色各不 ...

  5. ManualResetEven使用的最清楚说明

    ManualResetEven使用的最清楚说明 快速阅读 理解ManualResetEvent,以及如何使用. 官方说明 官方介绍:https://docs.microsoft.com/en-us/d ...

  6. html5中的fieldset/legend元素和keygen元素

    html5中的fieldset/legend元素和keygen元素 一.总结 一句话总结: fieldset/legend元素和figure和figcaption很像,只不过是作用于表单,前者表示内容 ...

  7. NPAPI插件开发详细记录:用VS2010开发NPAPI插件步骤<转>

    原帖地址:https://blog.csdn.net/z6482/article/details/7660748 ------------------------------------------- ...

  8. 【idea】idea远程调试代码

    一.前置条件 1.idea的代码和远程服务器代码保持一致 二.远程服务器配置 服务启动时,需要给jvm添加指定参数,进行启动 -agentlib:jdwp=transport=dt_socket,se ...

  9. Flutter -------- Drawer侧滑

    侧滑菜单在安卓App里面非常常见 抽屉通常与Scaffold.drawer属性一起使用.抽屉的子项通常是ListView,其第一个子项是DrawerHeader ,它显示有关当前用户的状态信息.其余的 ...

  10. bat 获取 exe 文件中 产品版本号并存储到变量中

    set EXE='D:\gitlab\drivereasy3\DriverEasyWPF\bin\Release\DriverEasy.exe' powershell "(Get-Item ...