生产者消费者问题

Java实现生产者消费者

我只是一个虾纸丫 提交于 2020-01-25 06:42:54
方法1:最简单--利用LinkedBlockingQueue 队列具有先进先出的特点,成为经常应用于生产-消费者模式的数据结构。 1.将一个对象放到队列尾部,如果队列已满,就等待直到有空闲节点。 ——put()方法 2.从队列头部取一个对象,如果没有对象,就等待直到有对象可取。 ——take()方法 3.在存取队列的过程中,锁定队列对象,不允许其它线程访问队列。——使得它是线程安全的 下面的代码适用于多个生产者、多个消费者。 1 //Producer.java 2 import java.util.concurrent.BlockingQueue; 3 4 /* 5 * Usage example, based on a typical producer-consumer scenario. 6 * Note that a <tt>BlockingQueue</tt> can safely be used with multiple 7 * producers and multiple consumers. 8 * <pre> 9 */ 10 class Producer implements Runnable { 11 private BlockingQueue<Object> queue; 12 13 Producer(BlockingQueue<Object> q) { 14

Java并发--线程间协作的两种方式:wait、notify、notifyAll和Condition

半世苍凉 提交于 2020-01-25 06:42:00
  在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作。比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权。因为生产者如果不释放对临界资源的占用权,那么消费者就无法消费队列中的商品,就不会让队列有空间,那么生产者就会一直无限等待下去。因此,一般情况下,当队列满时,会让生产者交出对临界资源的占用权,并进入挂起状态。然后等待消费者消费了商品,然后消费者通知生产者队列有空间了。同样地,当队列空时,消费者也必须等待,等待生产者通知它队列中有商品了。这种互相通信的过程就是线程间的协作。   今天我们就来探讨一下Java中线程协作的最常见的两种方式:利用Object.wait()、Object.notify()和使用Condition   以下是本文目录大纲:    一.wait()、notify()和notifyAll()   二.Condition    三.生产者-消费者模型的实现   转载原文链接:http://www.cnblogs.com/dolphin0520/p/3920385.html 一.wait()、notify()和notifyAll()   wait()、notify()和notifyAll()是 Object类中的方法: /** * Wakes

10 阻塞队列 & 生产者-消费者模式

旧城冷巷雨未停 提交于 2020-01-24 02:40:11
原文:http://www.cnblogs.com/dolphin0520/p/3932906.html 在前面我们接触的队列都是非阻塞队列,比如PriorityQueue、LinkedList(LinkedList是双向链表,它实现了Dequeue接口)。 使用非阻塞队列的时候有一个很大问题就是:它不会对当前线程产生阻塞,那么在面对类似消费者-生产者的模型时,就必须额外地实现同步策略以及线程间唤醒策略,这个实现起来就非常麻烦。但是有了阻塞队列就不一样了,它会对当前线程产生阻塞,比如一个线程从一个空的阻塞队列中取元素,此时线程会被阻塞直到阻塞队列中有了元素。当队列中有元素后,被阻塞的线程会自动被唤醒(不需要我们编写代码去唤醒)。这样提供了极大的方便性。 本文先讲述一下java.util.concurrent包下提供主要的几种阻塞队列,然后分析了阻塞队列和非阻塞队列的中的各个方法,接着分析了阻塞队列的实现原理,最后给出了一个实际例子和几个使用场景。    一.几种主要的阻塞队列 自从Java 1.5之后,在java.util.concurrent包下提供了若干个阻塞队列,主要有以下几个: ArrayBlockingQueue:基于数组实现的一个阻塞队列,在创建ArrayBlockingQueue对象时必须制定容量大小。 并且可以指定公平性与非公平性,默认情况下为非公平的

011程序、进程、线程的概念+Java中多线程的创建和使用+线程的生命周期+线程的同步+线程的死锁问题

孤街浪徒 提交于 2020-01-21 23:54:38
一.程序、进程、线程的概念 基本概念 程序(program)是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。 进程(process)是程序的一次执行过程,或是正在运行的一个程序。动态过程:有它自身的产生、存在和消亡的过程。如:运行中的QQ,运行中的MP3播放器;程序是静态的,进程是动态的。 线程(thread)进程可进一步细化为线程,是一个程序内部的一条执行路径。若一个程序可同一时间执行多个线程,就是支持多线程的。 何时需要多线程:程序需要同时执行两个或多个任务;程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、网络操作、搜索等:需要一些后台运行的程序时。 二.Java中多线程的创建和使用 多线程的创建和启动 Java语言的JVM允许程序运行多个线程,它通过java.lang.Thread类来实现。 Thread类的特性:每个线程都是通过某个特定的Thread对象的run()方法来完成操作的,经常把run()方法的主体称为线程体。通过该Thread对象的start()方法来调用这个线程。 背景:只使用单个线程完成多个任务(调用多个方法),肯定比多个线程来完成用的时间更短,为何仍然需要多线程呢? 多线程程序的优点:提高应用程序的响应。对图形化界面更有意义,可增强用户体验。提高计算机系统CPU的利用率。 改善程序结构

20-Python-queue队列

别来无恙 提交于 2020-01-21 07:55:02
队列分为线程队列和进程队列。线程队列只用于多个线程之间进行数据交互,不能跨进程通信;进程队列用于父进程与子进程,或者属于同一父进程下多个子进程进行交互,不能跨进程通信。 1、FIFO FIFO = First in First out,先进先出队列 1 import queue 2 3 4 q = queue.Queue() # first in first out 5 6 q.put(1) # 放数据 7 q.put(2) 8 q.put("d1") 9 q.put("d2") 10 11 print(q.get()) 12 print(q.get()) 13 print(q.get()) 14 print(q.get()) 15 print(q.get_nowait()) # 如果用q.get()取不到数据,则会进入卡死状态 2、LIFO 后进先出队列 = Last in First out 1 import queue 2 3 q1 = queue.LifoQueue() # last in first out 4 q1.put(1) 5 q1.put(2) 6 q1.put(3) 7 8 print(q1.get()) 9 print(q1.get()) 10 print(q1.get()) 3、PriorityQueue 优先级队列,Lowest First,越小越优先

Python--10、生产者消费者模型

帅比萌擦擦* 提交于 2020-01-21 07:35:24
生产者消费者模型(★) 平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。 程序中有两类角色:生产数据、消费数据 实现方式:生产->队列->消费。 通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。 通过队列的方式实现了程序解耦(生产者不需要管消费者的消费能力,不断的生产) #消息队列作为中间件,接受生产者发来的消息,并且供消费者拿走进行消费。 实现了异步\ 示例: from multiprocessing import Process,Queue import time,random,os def consumer(q): while True: res=q.get() time.sleep(random.randint(1,3)) print('\033[45m%s 吃 %s\033[0m' %(os.getpid(),res)) def producer(q): for i in range(10): time.sleep(random.randint(1,3)) res='卤肉%s' %i q.put(res) print('\033

生产者消费者

▼魔方 西西 提交于 2020-01-21 05:52:47
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。 在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。 什么是生产者消费者模式 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。 相关赞助商 全球架构师峰会,7月17日-18日,深圳大梅沙京基海湾大酒店。 马上报名 。 来源: https://www.cnblogs.com/biglucky/p/4642709.html

rabbitmq讲解

青春壹個敷衍的年華 提交于 2020-01-20 18:23:03
五种消息模型 RabbitMQ提供了6种消息模型,但是第6种其实是RPC,并不是MQ,因此不予学习。那么也就剩下5种。 simple简单模式 work工作模式(资源的竞争) 一个生产者,多个消费者,每个消费者获取到的消息唯一 publish/subscribe发布订阅(共享资源) 一个生产者发送的消息会被多个消费者获取。 routing路由模式 发送消息到交换机并且要指定路由key ,消费者将队列绑定到交换机时需要指定路由key topic 主题模式(路由模式的一种) 将路由键和某模式进行匹配,此时队列需要绑定在一个模式上,“#”匹配一个词或多个词,“*”只匹配一个词。 我们通过代码工程来了解RabbitMQ的工作方式: 依赖: < properties > < java.version > 1.8 </ java.version > < maven.compiler.source > ${java.version} </ maven.compiler.source > < project.build.sourceEncoding > UTF-8 </ project.build.sourceEncoding > < maven.compiler.target > ${java.version} </ maven.compiler.target > </ properties >

[java多线程] java并发编程之BlockingQueue

吃可爱长大的小学妹 提交于 2020-01-19 15:13:13
前言: 多线程在我们实际开发中使用比较多,因为最近也在使用BlockingQueue,所以也准备在这里总结一下,方便以后自己的查找。 BlockingQueue BlockingQueue是Concurrent包中的,很好的解决了多线程中,如何高效安全"传输"数据的问题。我们可以通过这些高效并且线程安全的队列类,为我们搭建高质量的多线程程序。 BlockingQueue即阻塞队列,他就是一个队列,在数据结构中大致如下图所示: 通过一个共享队列,使得数据由队列的一端输入,从另外一端输出。 在多线程的环境中,可以通过队列实现数据的共享,例如生产者和消费者模型,通过队列可以实现两者之间的数据共享。 经过前面的介绍,我们来看一下BlockingQueue的阻塞场景: 通过上图我们可以看出,再队列中没有数据的情况下,消费者端的所有线程都会被自动阻塞(挂起),直到有数据放入队列。 如上图所示,当队列中填满数据的情况下,生产者端的所有线程都会被自动阻塞(挂起),直到队列中所有空的位置,线程被自动唤醒。 BlockingQueue核心方法 BlockingQueue对不能满足条件的操作,提供了四种处理方式: 直接抛出异常,抛出异常。如果队列已满,添加元素会抛出IIIegalStateException异常;如果队列为空,获取元素会抛出NoSuchElementException异常。

IPC机制和生产者消费者模型

六月ゝ 毕业季﹏ 提交于 2020-01-19 12:40:12
IPC机制:(解决进程间的数据隔离问题)   进程间通信:IPC(inter-Process Comminication)   创建共享的进程列队,Queue 是多进程的安全列队,可以使用Queue 实现多进程之间的数据传递   底层实现:管道+锁的方式实现 # Queue([maxsize]) 创建共享的进程队列。maxsize是队列中允许的最大项数。如果省略此参数,则无大小限制。底层队列使用管道和锁定实现。另外,还需要运行支持线程以便队列中的数据传输到底层管道中。 Queue的实例q具有以下方法: q.get( [ block [ ,timeout ] ] ) 返回q中的一个项目。如果q为空,此方法将阻塞,直到队列中有项目可用为止。block用于控制阻塞行为,默认为True. 如果设置为False,将引发Queue.Empty异常(定义在Queue模块中)。timeout是可选超时时间,用在阻塞模式中。如果在制定的时间间隔内没有项目变为可用,将引发Queue.Empty异常。 q.get_nowait( ) 同q.get(False)方法。 q.put(item [, block [,timeout ] ] ) 将item放入队列。如果队列已满,此方法将阻塞至有空间可用为止。block控制阻塞行为,默认为True。如果设置为False,将引发Queue.Empty异常