Java基础教程:多线程基础(3)——阻塞队列

时间:2022-01-25 01:58:52

Java多线程基础:生产者/消费者模型

生产者/消费者模型

  生产者消费者模型是多线程协作的经典模型,生产者线程负责产出数据,消费者线程负责消费生产者生产的数据,数据存放在共享区域内。该模型旨在合理的指导生产者和消费者进行生产或消费,避免过量生产以及无法消费的等问题。

  Java基础教程:多线程基础(3)——阻塞队列

 首先生产者和消费者互相解耦,那线程同步的重任放在了共享区域内:

  • 当共享区域存满时,阻塞生产者,防止其继续生产。
  • 当共享区域清空时,阻塞消费者,防止其继续消费。   

说明:这里的阻塞并不等同指线程的阻塞态,实现阻塞的方式有很多种 。 

  1. 线程调用sleep。
  2. 线程调用阻塞式IO方法,在该方法返回前,该线程被阻塞。
  3. 线程试图获得一个同步监视器,但该同步监视器正在被其他线程所持有。
  4. 线程等待某个通知。
  5. 程序调用了suspend方法将该线程挂起,非常容易导致死锁,避免即可。 

基于等待/唤醒机制实现模型

实现原理

  object.wait()方法的作用是使当前执行代码的线程进入等待态,该方法用来将当前线程置入“预执行队列”,并在wait所在的代码行处停止执行,直到接到通知或被中断为止。wait方法会释放锁,所以它一定是在同步方法或同步代码块中使用。

  obejct.notify()方法也是在同步方法或者同步块中使用,该方法用于通知那些可能等待该对象的对象锁的其他线程,如果有多个线程等待,则由线程规划器随机挑选出其中一个呈wait状态的线程,对其发出通知notify,并使它等待获取该对象的对象锁。

说明:在执行notify方法后,当前线程不会马上释放该对象锁,呈wait状态的线程也并不能马上获取该对象锁,要等到执行notify方法的线程将程序执行完,也就是退出Synchronized代码块后,才会释放锁,而呈wait状态所在的线程才可以获取该对象锁

  一句话总结就是:wait是线程停止运行,已达到阻塞的目的,而notify使停止的线程继续运行。它们两个互相配合,以实现线程间相互通信

代码实现

生产者,负责生产数据。

class Producer extends Thread{
private Buffer buffer;
public Producer(Buffer buffer){
this.buffer = buffer;
}
@Override
public void run() {
for (int i=0;i<10;i++){
try {
buffer.add(i);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

消费者,负责消费数据。

class Consumer extends Thread{
private Buffer buffer;
public Consumer(Buffer buffer){
this.buffer = buffer;
}
@Override
public void run() {
for(int i=0;i<10;i++){
try {
System.out.println(buffer.pull());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

缓存区,即共享区域。

class Buffer{
private Queue<Integer> list;
private int size; public Buffer(int size) {
list = new LinkedList<>();
this.size = size;
} public void add(int val) throws InterruptedException {
synchronized (this){
if(list.size()>=size)
wait();
list.add(val);
notify();
}
} public int pull() throws InterruptedException {
synchronized (this){
if(list.size()==0)
wait();
int val = list.poll();
notify();
return val;
}
} }

  

参考资料

  • 《Java多线程编程艺术》

Java基础教程:多线程基础(3)——阻塞队列的更多相关文章

  1. Java中常用的七个阻塞队列介绍第一篇

    Java中常用的七个阻塞队列介绍第一篇 在上一篇我们对Java中的队列分类做了简单的介绍.本文咱们主要来聊聊阻塞队列中的七个常用子类.这七个阻塞队列的学习步骤:先看源码,分析完源码之后,我们再来对每个 ...

  2. Java中常用的七个阻塞队列第二篇DelayQueue源码介绍

    Java中常用的七个阻塞队列第二篇DelayQueue源码介绍 通过前面两篇文章,我们对队列有了了解及已经认识了常用阻塞队列中的三个了.本篇我们继续介绍剩下的几个队列. 本文主要内容:通过源码学习De ...

  3. Java核心知识点学习----多线程中的阻塞队列&comma;ArrayBlockingQueue介绍

    1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过s ...

  4. Java多线程-新特征-阻塞队列ArrayBlockingQueue

    阻塞队列是Java5线程新特征中的内容,Java定义了阻塞队列的接口java.util.concurrent.BlockingQueue,阻塞队列的概念是,一个指定长度的队列,如果队列满了,添加新元素 ...

  5. java多线程8:阻塞队列与Fork&sol;Join框架

    队列(Queue),是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的. BlockingQueue 而阻塞队列BlockingQueue除了继承 ...

  6. java多线程系列10 阻塞队列模拟

    接下来的几篇博客会介绍下juc包下的相关数据结构 包含queue,list,map等 这篇文章主要模拟下阻塞队列. 下面是代码 import java.util.LinkedList; import ...

  7. java中的多线程 &sol;&sol; 基础

    java 中的多线程 简介 进程 : 指正在运行的程序,并具有一定的独立能力,即 当硬盘中的程序进入到内存中运行时,就变成了一个进程 线程 : 是进程中的一个执行单元,负责当前程序的执行.线程就是CP ...

  8. Java设计模式—生产者消费者模式(阻塞队列实现)

    生产者消费者模式是并发.多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据.这篇文章我们来看看什么是生产者消费者模式,这个问 ...

  9. Java并发编程(十)阻塞队列

    使用非阻塞队列的时候有一个很大问题就是:它不会对当前线程产生阻塞,那么在面对类似消费者-生产者的模型时,就必须额外地实现同步策略以及线程间唤醒策略,这个实现起来就非常麻烦.但是有了阻塞队列就不一样了, ...

  10. Java并发(7):阻塞队列

    在前面我们接触的队列都是非阻塞队列,比如PriorityQueue.LinkedList(LinkedList是双向链表,它实现了Dequeue接口). 使用非阻塞队列的时候有一个很大问题就是:它不会 ...

随机推荐

  1. &period;net 生成 静态页面

    .net 生成 静态页面 <!--Main.Aspx--> <%@ page language="C#" %> <%@ import namespac ...

  2. Win7打补丁以后vs2012突然出现的程序版本不兼容问题

    装这个: Update for Microsoft Visual Studio 2012 (KB2781514) http://www.microsoft.com/en-us/download/det ...

  3. jsonp与ajax

    jsonp思维导图:1.定义2.为什么用3.json原理4.优缺点何为跨域?何为JSONP?JSONP技术能实现什么?是否有必要使用JSONP技术? JSON和JSONP??虽然只有一个字母的差别,但 ...

  4. Throwing cards away I

    Throwing cards away I   Given is an ordered deck of n cards numbered 1 to n with card 1 at the top a ...

  5. (八)boost库之异常处理

    (八)boost库之异常处理 当你面对上千万行的项目时,当看到系统输出了异常信息时,你是否想过,如果它能将文件名.行号等信息输出,该多好啊,曾经为此绞尽脑汁. 今天使用boost库,将轻松的解决这个问 ...

  6. 微信小程序 网络请求之设置合法域名

    设置域名 登录微信公众号后台小程序中 设置→开发设置→服务器设置 必须设置域名,微信小程序才能进行网络通讯,不然会报错 如果设置好了合法域名,开发工具还提示不在合法域名列表中,因为在微信会有一段时间的 ...

  7. latex 生成pdf

    我个人还是比较推崇传统的方法:先生成dvi,在生成pdf. 直接在winEdt中点击最下方的Windows Command Prompt, 否则从cmd进入命令行的话,还要进入tex文件夹,好麻烦. ...

  8. JavaScript新手入门 贪吃蛇

    从小就在玩贪吃蛇,但是知道今天自己做了一遍才知道原理的具体的实现步骤. 刚进入界面时显示开始游戏(不重要,本人比较喜欢吹毛求疵) 中间黑色部分为游戏的主要展示部分 主要步骤及源码: body中代码,红 ...

  9. python 安装influxdb-python

    一.Linux下安装 1.yum install -y git 2.安装pip,参考:https://app.yinxiang.com/shard/s41/sh/0338ba85-5443-453f- ...

  10. eclipse几种常见问题的解决

    build项目时出现卡死现象的解决方案 场景:在使用使用Eclipse编辑文件保存时或者build项目时,经常出现卡死现象,此时即便杀死eclipse进程重启还是依然出现这种现象. 原因:eclips ...