多线程-生产者消费者模式-CopyOnWriteArrayList索引越界问题
为什么消费者会出现索引越界呢?
因为缓冲区消费判定时候使用了if判断,wait() 被叫醒后,如果其他线程已经抢到了对象锁并且已经消费了一个产品后,那么产品就为0了,现在直接进行取产品就会发生索引越界,所以此时应该使用while循环 使其一直判定 是否为0 是0就等待 继续抢 往复循环
缓冲区:
public class OrderPool {private CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();//生产者放入订单public synchronized void produceOrder() {while (list.size() == 30) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}list.add("order");this.notifyAll();System.out.println(Thread.currentThread().getName() + "---->生产一个订单,还有" + list.size() + "个订单");try {TimeUnit.MILLISECONDS.sleep(300L);} catch (InterruptedException e) {e.printStackTrace();}}/*** 为什么下面判断条件用if的时候会报索引越界呢?* 因为该线程醒了之后要再次判断是否为0* 因为不知道等待的时候其他线程是否更新了 list.size()* 若此时其他消费者已经消费了商品 但是自己又没有判断lise.size() 是否为0 此时取出第一个订单 就会出现索引越界* 所以此时应该使用while一直判断是否为0 如果为0 继续等待*/public synchronized void consumerOrder() {while (list.size() == 0) {System.out.println("订单池没有订单,消费者等待中");try {//只能用在同步方法 或者同步代码块中/*调用wait()方法后 立刻释放对象锁 线程进入当前对象的等待池* 被唤醒之后,要拿到对象锁后才可以继续执行* 若没有拿到对象锁 则会一直等待*/this.wait();} catch (InterruptedException e) {e.printStackTrace();}}//若订单池中有订单 就消耗一个订单list.remove(0);// this.notify(); 也是只能出现在同步代码块中 notify() 随机唤醒一个线程this.notifyAll();System.out.println(Thread.currentThread().getName() + "---->消费一个订单,还有" + list.size() + "个");try {TimeUnit.MILLISECONDS.sleep(200L);} catch (InterruptedException e) {e.printStackTrace();}}
}
消费者:
public class Consumer implements Runnable {private OrderPool orderPool;public Consumer() {}public Consumer(OrderPool orderPool) {this.orderPool = orderPool;}@Overridepublic void run() {while (true) {orderPool.consumerOrder();}}
}
生产者:
public class Produce implements Runnable {private OrderPool orderPool;public Produce() {}public Produce(OrderPool orderPool) {this.orderPool = orderPool;}@Overridepublic void run() {while (true) {orderPool.produceOrder();}}
}
多线程-生产者消费者模式-CopyOnWriteArrayList索引越界问题相关推荐
- java多线程-生产者消费者模式
进程定义: 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位 线程定义: 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能 ...
- 多线程—生产者消费者模式、银行家算法
Synchronized实现 import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;pu ...
- 【C++】多线程(链式、循环队列)实现生产者消费者模式
生产者消费者模式: 生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同 ...
- 多线程终极模式:生产者-消费者模式
多线程de小事情 导航不迷路: 程序.进程以及线程的爱恨情仇 最简单实现多线程的方法(Thread) 简单易懂的多线程(通过实现Runnable接口实现多线程) 常用获取线程基本信息的方法(新手专属) ...
- [19/04/11-星期四] 多线程_并发协作(生产者/消费者模式_2种解决方案(管程法和信号灯法))...
一.概念 多线程环境下,我们经常需要多个线程的并发和协作.这个时候,就需要了解一个重要的多线程并发协作模型"生产者/消费者模式". Ø 什么是生产者? 生产者指的是负责生产数据的模 ...
- java消费者生产者设计模式_java 多线程并发设计模式之四: 生产者消费者模式
生产者消费者模式是一个经典的多线程设计模式,其核心思想是:有两类线程和一个内存缓冲区或者队列, 一类线程发起任务,并提交到队列中.另一类线程用来处理这些任务,叫做消费者线程. 这两类线程进行通信的桥梁 ...
- Java多线程学习三:有哪几种实现生产者消费者模式的方法
我们先来看看什么是生产者消费者模式,生产者消费者模式是程序设计中非常常见的一种设计模式,被广泛运用在解耦.消息队列等场景.在现实世界中,我们把生产商品的一方称为生产者,把消费商品的一方称为消费者,有时 ...
- 并发编程(五)python实现生产者消费者模式多线程爬虫
并发编程专栏系列博客 并发编程(一)python并发编程简介 并发编程(二)怎样选择多线程多进程和多协程 并发编程(三)Python编程慢的罪魁祸首.全局解释器锁GIL 并发编程(四)如何使用多线程, ...
- 多线程-并发编程(7)-生产者消费者模式及非阻塞队列与阻塞队列实现
生产者消费者模式是一个十分经典的多线程协作模式 弄懂生产者消费者问题能够让我们对多线程编程的理解更加深刻 存在3个元素 1.生产者(类比厨师) 2.生产者的生产产品(类比美食) 3.消费者(类比吃货) ...
- Java多线程(含生产者消费者模式详解)
多线程 导航 多线程 1 线程.进程.多线程概述 2 创建线程 (重点) 2.1 继承Thread类(Thread类也实现了Runnable接口) 2.2 实现Runnable接口(无消息返回) 2. ...
最新文章
- 50 年人类登月史:那些不为人知的故事
- 时间同步失败_跨系统历史数据同步脚本实战
- 升级到 Tomcat 8 后 Cookie 可能出现的问题
- strstr不区分大小写_Excel find 函数竟然还能这么用!奖金梯次计算,连 if 都不需要...
- 设计界新人不用再苦找资源网站啦!一流导航神器收藏起来!
- c语言学习-对从键盘输入的一个字符串中的大英字母及数字进行计数
- AcWing 240. 食物链
- Java开发自行车管理项目要求_java毕业设计_springboot框架的公共自行车租赁管理...
- 软件测试的八股文内容
- Redhat7 安装 yum
- 筹备酒吧之路——音响篇
- Ubuntu安装Linux网页版微信
- cgcs2000大地坐标系地图_MapGIS国土空间数据2000大地坐标系转换系统
- 基于asp.net的排球赛事网站设计与实现
- ~_~ 搬家啰 ~_~
- python实现简单舒尔方格
- 使用 OpenCV 在 Python 中检测图像中的形状
- Linux 密码 shadow
- www.0 php.com,PHPcom 内容管理系统
- 【磁屏蔽电感】里让工程师“头晕脑胀”的问题