首先 LinkedBlockingQueue 是线程安全的阻塞队列,LinkedBlockingQueue实现的生产者和消费者模型

阻塞队列与我们平常接触的普通队列(LinkedList或ArrayList等)的最大不同点,在于阻塞队列支出阻塞添加和阻塞删除方法。

阻塞添加:所谓的阻塞添加是指当阻塞队列元素已满时,队列会阻塞加入元素的线程,直队列元素不满时才重新唤醒线程执行元素加入操作。

阻塞删除:阻塞删除是指在队列元素为空时,删除队列元素的线程将被阻塞,直到队列不为空再执行删除操作(一般都会返回被删除的元素)

BlockingQueue的核心方法:
放入数据:
  offer(anObject):表示如果可能的话,将anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回false.(本方法不阻塞当前执行方法的线程)
  offer(E o, long timeout, TimeUnit unit):可以设定等待的时间,如果在指定的时间内,还不能往队列中加入BlockingQueue,则返回失败。
  put(anObject):把anObject加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程被阻断直到BlockingQueue里面有空间再继续.
获取数据:
  poll(time):取走BlockingQueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,取不到时返回null;
  poll(long timeout, TimeUnit unit):从BlockingQueue取出一个队首的对象,如果在指定时间内,队列一旦有数据可取,则立即返回队列中的数据。否则知道时间超时还没有数据可取,返回失败。
  take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的数据被加入;
  drainTo():一次性从BlockingQueue获取所有可用的数据对象(还可以指定获取数据的个数),通过该方法,可以提升获取数据效率;不需要多次分批加锁或释放锁。

如果不指定队列的容量大小,也就是使用默认的Integer.MAX_VALUE,如果存在添加速度大于删除速度时候,有可能会内存溢出(OOM)

写法一:

生产者 Producer.java

package com.vipsoft.web.app;

import java.util.concurrent.LinkedBlockingQueue;

public class Producer extends Thread {
//1、通过构造函数传入阻塞队列
public static LinkedBlockingQueue<String> queue; public Producer(LinkedBlockingQueue<String> queue) {
this.queue = queue;
} public void run() {
int i = 0;
while (true) {
i++;
try {
String msg = "P" + i;
queue.put(msg);
System.out.println("我生产了 => " + msg + " 队列数量 " + queue.size());
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Producer queue.size => " + queue.size());
e.printStackTrace();
}
}
}
}

消费者 Consumer.java

package com.vipsoft.web.app;

import java.util.concurrent.LinkedBlockingQueue;

public class Consumer extends Thread {
public static LinkedBlockingQueue<String> queue; public Consumer(LinkedBlockingQueue<String> queue) {
this.queue = queue;
} public void run() {
while (true) {
try {
System.out.println("我消费了 => " + queue.take() + " 队列数量 " + queue.size());
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println("Consumer queue.size() => " + queue.size());
e.printStackTrace();
} }
}
}

主程序

package com.vipsoft.web.app;

import java.util.concurrent.LinkedBlockingQueue;

public class LinkedBlockingQueueTest {

    public static void main(String[] args) {

        //1、创建一个BlockingQueue
int MAX_NUM = 10; //实际使用也需要指定大小,防止OOM
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>(MAX_NUM); //2、创建一个生产者,一个消费者
Producer producer = new Producer(queue);
Consumer consumer = new Consumer(queue); //3、开启两个线程
producer.start();
consumer.start(); }
}

写法二:

package com.vipsoft.web.app;

import java.util.concurrent.LinkedBlockingDeque;

public class LinkedBlockingQueueTest {

    public static void main(String[] args) {

        final LinkedBlockingDeque<String> queue = new LinkedBlockingDeque<>(10); //实际使用也需要指定大小,防止OOM

        Runnable producerRunnable = new Runnable() {
public void run() {
int i = 0;
while (true) {
i++;
try {
String msg = "P" + i;
queue.put(msg);
System.out.println("我生产了 => " + msg + " 队列数量 " + queue.size());
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Producer queue.size => " + queue.size());
e.printStackTrace();
}
}
}
}; Runnable customerRunnable = new Runnable() {
public void run() {
while (true) {
try {
System.out.println("我消费了 => " + queue.take() + " 队列数量 " + queue.size());
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println("Consumer queue.size() => " + queue.size());
e.printStackTrace();
}
}
}
}; Thread thread1 = new Thread(producerRunnable);
thread1.start(); Thread thread2 = new Thread(customerRunnable);
thread2.start();
}
}

LinkedBlockingQueue实现的生产者和消费者模型的更多相关文章

  1. Java线程(学习整理)--4---一个简单的生产者、消费者模型

     1.简单的小例子: 下面这个例子主要观察的是: 一个对象的wait()和notify()使用情况! 当一个对象调用了wait(),那么当前掌握该对象锁标记的线程,就会让出CPU的使用权,转而进入该对 ...

  2. Python之生产者&、消费者模型

    多线程中的生产者和消费者模型: 生产者和消费者可以用多线程实现,它们通过Queue队列进行通信. import time,random import Queue,threading q = Queue ...

  3. 【java线程系列】java线程系列之线程间的交互wait()/notify()/notifyAll()及生产者与消费者模型

    关于线程,博主写过java线程详解基本上把java线程的基础知识都讲解到位了,但是那还远远不够,多线程的存在就是为了让多个线程去协作来完成某一具体任务,比如生产者与消费者模型,因此了解线程间的协作是非 ...

  4. Spring MVC 使用介绍(七)—— 注解式控制器(三):生产者与消费者模型

    一.MIME类型 MIME类型格式:type/subtype(;parameter)? type:主类型,任意的字符串,如text,如果是*号代表所有 subtype:子类型,任意的字符串,如html ...

  5. 守护进程,互斥锁,IPC,队列,生产者与消费者模型

    小知识点:在子进程中不能使用input输入! 一.守护进程 守护进程表示一个进程b 守护另一个进程a 当被守护的进程结束后,那么守护进程b也跟着结束了 应用场景:之所以开子进程,是为了帮助主进程完成某 ...

  6. python queue和生产者和消费者模型

    queue队列 当必须安全地在多个线程之间交换信息时,队列在线程编程中特别有用. class queue.Queue(maxsize=0) #先入先出 class queue.LifoQueue(ma ...

  7. python并发编程之守护进程、互斥锁以及生产者和消费者模型

    一.守护进程 主进程创建守护进程 守护进程其实就是'子进程' 一.守护进程内无法在开启子进程,否则会报错二.进程之间代码是相互独立的,主进程代码运行完毕,守护进程也会随机结束 守护进程简单实例: fr ...

  8. 人生苦短之我用Python篇(队列、生产者和消费者模型)

    队列: queue.Queue(maxsize=0) #先入先出 queue.LifoQueue(maxsize=0) #last in fisrt out  queue.PriorityQueue( ...

  9. python:生产者与消费者模型

    1,生产者与消费者模型的矛盾在于数据供需的不平衡 import time import random from multiprocessing import Queue from multiproce ...

  10. 生产者和消费者模型producer and consumer(单线程下实现高并发)

    #1.生产者和消费者模型producer and consumer modelimport timedef producer(): ret = [] for i in range(2): time.s ...

随机推荐

  1. 原生JS实现视频截图

    视频截图效果预览 利用Canvas进行截图 要用原生js实现视频截图,可以利用canvas的绘图功能 ctx.drawImage,只需要获取到视频标签,就可以通过drawImage把视频当前帧图像绘制 ...

  2. 最小的k个数 (3.20 leetcode每日打卡)

    输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 示例 1: 输入:arr = [3,2,1], k = 2 输 ...

  3. 面向对象java前三次pta作业

    目录: 1.前言 2.设计与分析 3.踩坑心得 4.主要困难及改进建议 5.总结 1.前言 面向对象程序设计(Object-Oriented Programming,简称OOP)是一种编程范式,它以对 ...

  4. python之封装及私有方法

    目录 封装 简洁 私有方法 封装:提高程序的安全性 将属性和方法包装到类对象中,在方法内部对属性进行操作,在类对象外部调用方法,使得程序更加简洁 在python中,如果该属性不希望在类对象外部被访问, ...

  5. 一篇文章带你掌握Web自动化测试工具——Selenium

    一篇文章带你掌握Web自动化测试工具--Selenium 在这篇文章中我们将会介绍Web自动化测试工具Selenium 如果我们需要学习相关内容,我们需要掌握Python,PyTest以及部分前端知识 ...

  6. 旺店通·企业奇门和用友BIP接口打通对接实战

    旺店通·企业奇门和用友BIP接口打通对接实战 接通系统:旺店通·企业奇门 旺店通是北京掌上先机网络科技有限公司旗下品牌,国内的零售云服务提供商,基于云计算SaaS服务模式,以体系化解决方案,助力零售企 ...

  7. 【Android】如何去掉默认标题栏

    1.在AndroidManifest.xml文件中修改并添加以下代码 android:theme="@style/Theme.AppCompat.NoActionBar" 2.在你 ...

  8. AtCoder_abc330

    AtCoder_abc330 比赛链接 A - Counting Passes A题链接 题目大意 给出\(N\)个数\(a_1,a_2,a_3\cdots,a_N\),和一个正整数\(L\).输出有 ...

  9. c# 高并发必备技巧(三)

    前面两篇文章主要是介绍了如何解决高并发情况下资源争夺的问题.但是现实的应用场景中除了要解决资源争夺问题,高并发的情况还需要解决更多问题,比如快速处理业务数据等, 本篇文章简要罗列一下与之相关的更多技术 ...

  10. Net 高级调试之十二:垃圾回收机制以及终结器队列、对象固定

    一.简介 今天是<Net 高级调试>的第十二篇文章,这篇文章写作时间的跨度有点长.这篇文章我们主要介绍 GC 的垃圾回收算法,什么是根对象,根对象的存在区域,我们也了解具有析构函数的对象是 ...