Java基础教程:多线程基础(3)——阻塞队列
Java多线程基础:生产者/消费者模型
生产者/消费者模型
生产者消费者模型是多线程协作的经典模型,生产者线程负责产出数据,消费者线程负责消费生产者生产的数据,数据存放在共享区域内。该模型旨在合理的指导生产者和消费者进行生产或消费,避免过量生产以及无法消费的等问题。
首先生产者和消费者互相解耦,那线程同步的重任放在了共享区域内:
- 当共享区域存满时,阻塞生产者,防止其继续生产。
- 当共享区域清空时,阻塞消费者,防止其继续消费。
说明:这里的阻塞并不等同指线程的阻塞态,实现阻塞的方式有很多种 。
- 线程调用sleep。
- 线程调用阻塞式IO方法,在该方法返回前,该线程被阻塞。
- 线程试图获得一个同步监视器,但该同步监视器正在被其他线程所持有。
- 线程等待某个通知。
- 程序调用了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)——阻塞队列的更多相关文章
- Java中常用的七个阻塞队列介绍第一篇
Java中常用的七个阻塞队列介绍第一篇 在上一篇我们对Java中的队列分类做了简单的介绍.本文咱们主要来聊聊阻塞队列中的七个常用子类.这七个阻塞队列的学习步骤:先看源码,分析完源码之后,我们再来对每个 ...
- Java中常用的七个阻塞队列第二篇DelayQueue源码介绍
Java中常用的七个阻塞队列第二篇DelayQueue源码介绍 通过前面两篇文章,我们对队列有了了解及已经认识了常用阻塞队列中的三个了.本篇我们继续介绍剩下的几个队列. 本文主要内容:通过源码学习De ...
- Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍
1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过s ...
- Java多线程-新特征-阻塞队列ArrayBlockingQueue
阻塞队列是Java5线程新特征中的内容,Java定义了阻塞队列的接口java.util.concurrent.BlockingQueue,阻塞队列的概念是,一个指定长度的队列,如果队列满了,添加新元素 ...
- java多线程8:阻塞队列与Fork/Join框架
队列(Queue),是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的. BlockingQueue 而阻塞队列BlockingQueue除了继承 ...
- java多线程系列10 阻塞队列模拟
接下来的几篇博客会介绍下juc包下的相关数据结构 包含queue,list,map等 这篇文章主要模拟下阻塞队列. 下面是代码 import java.util.LinkedList; import ...
- java中的多线程 // 基础
java 中的多线程 简介 进程 : 指正在运行的程序,并具有一定的独立能力,即 当硬盘中的程序进入到内存中运行时,就变成了一个进程 线程 : 是进程中的一个执行单元,负责当前程序的执行.线程就是CP ...
- Java设计模式—生产者消费者模式(阻塞队列实现)
生产者消费者模式是并发.多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据.这篇文章我们来看看什么是生产者消费者模式,这个问 ...
- Java并发编程(十)阻塞队列
使用非阻塞队列的时候有一个很大问题就是:它不会对当前线程产生阻塞,那么在面对类似消费者-生产者的模型时,就必须额外地实现同步策略以及线程间唤醒策略,这个实现起来就非常麻烦.但是有了阻塞队列就不一样了, ...
- Java并发(7):阻塞队列
在前面我们接触的队列都是非阻塞队列,比如PriorityQueue.LinkedList(LinkedList是双向链表,它实现了Dequeue接口). 使用非阻塞队列的时候有一个很大问题就是:它不会 ...
随机推荐
- linux命令lsattr、chattr、man
1.man命令,可以查看手册 配置位置/etc/man.conf MANPATH决定手册查询位置 MANSECT决定man查询的顺序 man的查询 linux man的常用用法: man sectio ...
- 计算机网络自顶向下第三章传输层二TCP
TCP 全双工 A-B,B-A 点对点 一对一的 TCP连接建立过程 客户首先发送一个特殊的TCP报文段,服务器用另一个特殊的TCP报文段来相应,最后,客户再用第三个特殊的报文段作为相应,前两个报文段 ...
- 【温故知新】——CSS黑魔法小技巧可以少些不必要的js
前言:这篇文章是转载[前端开发博客]的一篇技术文章,并非本人所写.只是个人觉得很实用,所以分享给大家.原文链接:github.com 1.利用 CSS 的 content 属性 attr 抓取资料需求 ...
- shell中sed命令
sed -i '/cd ${LDIR_DEST}\/webextend\/pc && ln -s \/hard\/www_winclient\/bboxpc.exe ./a\ \tcd ...
- EXCel鼠标右键不能用解决办法
EXCel鼠标右键不能用解决办法 倒腾vba首要是保证安全,各路大神的代码非常神奇,莫名的就让你的excel嘎嘣了,如出现右键无法使用(确定不是您的鼠标问题),那么以下代码可完全修复设置.操作步骤:打 ...
- 【Excle数据透透视表】如何删除数据透视表
选中区域A4:C17,在键盘上按DELETE键删除,结果提示: 那么如何删除呢? 解决方案 选中整个数透视表,再删除 具体操作: 选中整个数据透视表→DELETE 注意:删除之后,源数据不会受到影响
- 【Python】合并(拼接)字符串
在很多情况下,我们都需要合并字符串.例如:需要将姓氏与名字存储在不同的变量中,然后显示的时候再将他们合二为一 first_name = 'oliver' last_name = 'smith' ful ...
- 【Android实战】Gallary+ImageSwicther图片查看器
仿照如今各大新闻站点图片新闻的浏览模式,上面展示详细图片(ImageSwitch),以下是能够滑动的小图片(Gallery). 当中须要注意的是ImageSwitch须要定义一个工厂返回的组件,而且能 ...
- Leetcode Array 16 3Sum Closest
Given an array S of n integers, find three integers in S such that the sum is closest to a given num ...
- 并发错误:事务(进程 ID )与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品
这个是并发情况下导致的数据库事务错误,先介绍下背景. 背景 springboot+springmvc+sqlserver+mybatis 一个controller里有五六个接口,这些接口都用到了spr ...