java阻塞队列作用_简单理解阻塞队列(BlockingQueue)中的take/put方法以及Condition存在的作用...

简单理解阻塞队列(BlockingQueue)中的take/put方法以及Condition存在的作用

Condition:可以理解成一把锁的一个钥匙,它既可以解锁(通知放行),又可以加锁(阻塞)

notFull:当队列元素满了时,阻塞生产,当队列元素存在元素但是没有满时,去通知消费

notEmpty:当队列中不存在元素时,阻塞消费,当队列元素存在元素时,去通知生产

while (count >= datas.length) {...}

while (count <= 0) {...}

两个while循环判断,而不用if,是因为线程不安全,

导致多线程场景下每个线程获取到的循环条件count的值存在差异,

导致代码执行异常,用while可以使当前线程重新刷新判断条件count的值。

用处:

ThreadPoolExecutor中使用到了阻塞队列,阻塞队列中又使用到了ReentrantLock,而ReentrantLock基于AQS。

package com.zhuyz.foundation.juc;

import java.util.concurrent.TimeUnit;

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.ReentrantLock;

public class MyArrayBlockingQueue {

// 数组元素

private T[] datas;

// 实际的元素个数(也有索引下标的作用)

private volatile int count;

private final ReentrantLock putLock = new ReentrantLock();

private final ReentrantLock takeLock = new ReentrantLock();

// 通知消费,暂停生产【当数组full时await(put时),当数组notFull时signal(take时)】

private Condition notFull = putLock.newCondition();

// 通知生产,暂停消费【当数组empty时await(take时),当数组notEmpty时signal(put时)】

private Condition notEmpty = takeLock.newCondition();

public MyArrayBlockingQueue(int cap) {

this.datas = (T[]) new Object[cap];

}

private void put(T t) {

final ReentrantLock putLock = this.putLock;

putLock.lock();

try {

// 线程不安全,需要循环判断,插入值之前判断一下数组长度是否达到最大长度

while (count >= datas.length) {

System.out.println("datas is full, please waiting take");

notFull.await();

}

datas[count++] = t;

System.out.println("put: " + t);

} catch (Exception e) {

System.out.println("异常" + e);

} finally {

putLock.unlock();

}

// 通知获取元素的线程继续执行(take_thread)

final ReentrantLock takeLock = this.takeLock;

takeLock.lock();

try {

notEmpty.signal();

} finally {

takeLock.unlock();

}

}

private T take() {

final ReentrantLock takeLock = this.takeLock;

takeLock.lock();

T t = null;

try {

// 线程不安全,需要循环判断,插入值之前判断一下数组中元素个数是否为0

while (count <= 0) {

System.out.println("datas is empty, please waiting put");

notEmpty.await();

}

// 获取元素

t = datas[--count];

System.out.println("take: " + t);

} catch (Exception e) {

System.out.println("异常" + e);

} finally {

takeLock.unlock();

}

final ReentrantLock putLock = this.putLock;

putLock.lock();

try {

// 通知插入元素的线程继续执行(put_thread)

notFull.signal();

} finally {

putLock.unlock();

}

return t;

}

public static void main(String[] args) throws InterruptedException {

MyArrayBlockingQueue myArrayBlockingQueue = new MyArrayBlockingQueue<>(5);

for (int i = 0; i < 10; i++) {

int finalI = i;

new Thread(() -> myArrayBlockingQueue.put(finalI)).start();

}

TimeUnit.SECONDS.sleep(5L);

for (int i = 0; i < 5; i++) {

new Thread(() -> myArrayBlockingQueue.take()).start();

}

}

}

结果如下:

从结果中可以看出,先put了5个元素,然后另外五个元素被阻塞住了,没有进去

take消费5个之后,另外五个被阻塞的元素就被put进去了

put: 0

put: 1

put: 2

put: 3

put: 4

datas is full, please waiting take

datas is full, please waiting take

datas is full, please waiting take

datas is full, please waiting take

datas is full, please waiting take

take: 4

put: 5

take: 5

take: 3

put: 6

put: 7

take: 7

put: 8

take: 8

put: 9

本文地址:https://blog.csdn.net/qq_43128724/article/details/110438987

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/288853.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

剑指offer之找出数组中重复数字

1 问题 给的N个数字的数组&#xff0c;每个元素的大小范围大于等于0小于N(0 << a[i] < N),找出数组中有哪些数字重复了并且这个数字重复了多少次&#xff0c;一共有几个数字重复了。 2思路 由于元素的大小范围大于等于0小于N(0 << a[i] < N),我们直接把这个…

tcp udp区别优缺点_一文搞懂TCP与UDP的区别

一、TCP协议&#xff1a;位于传输层&#xff0c; 提供可靠的字节流服务。所谓的字节流服务(Byte Stream Service) 是指&#xff0c; 为了方便传输&#xff0c; 将大块数据分割成以报文段(segment) 为单位的数据包进行管理。而可靠的传输服务是指&#xff0c; 能够把数据准确可靠…

C#趣味程序---水仙花数

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 水仙花数 {public partial class Fo…

《企业级ios应用开发实战》一导读

前 言 为什么写这本书随着我国3G网络和移动互联网的兴起&#xff0c;许多传统的企业应用正在从桌面向移动终端扩展&#xff0c;移动办公、移动营销、移动作业等需求日渐强烈。有迹象表明&#xff0c;传统的互联网正在向移动互联网发展。根据摩根士丹利发布的全球互联网发展趋势…

java获取map数量_java – 如何从HashMap或LinkedHashMap获取有限数量的值?

假设我有一个包含216个条目的LinkedHashMap,我如何从LinkedHashMap< Integer,Object>获取前100个值(此处为Object类型).解决方法:丑陋的单线这个丑陋的单线程会做(并在问题的情况下返回一个ArrayList< Object>)&#xff1a;Collections.list(Collections.enumerati…

对.NET未来的一点感悟

.NET诞生有20年了&#xff0c;一路走来起起伏伏&#xff0c;从开始的专注windows&#xff0c;到后来的跨平台&#xff1b;从之前的闭源&#xff0c;到现在的完全开源&#xff1b;从原来的win server(IIS)&#xff0c;到现在的紧密拥抱docker&#xff0c;.NET在成长&#xff0c;…

linux之安装frida遇到的问题

我想安装Hook家族神器的Frida工具 问题1 我一开始使用的命令如下 sudo pip install frida 然后提示错误如下 The directory /home/chenyu/.cache/pip/http or its parent directory is not owned by the current user and the cache has been disabled. Please check the …

为什么要选择Hibernate

2019独角兽企业重金招聘Python工程师标准>>> 见&#xff1a; http://onecan.iteye.com/blog/1387920 转载于:https://my.oschina.net/sniperLi/blog/416396

苹果手机5s无需越狱免流_苹果越狱手机端自签名插件

unc0ver越狱官网&#xff1a; https://github.com/pwn20wndstuff/Undecimus (此网站ipa需要签名)已经签名网站&#xff1a; https://jailbreaks.fun/支持iOS11.0~12.1.3~12.4 支持 iPhone5S/SE/6/6P/6S/6SP…

面向对象之迪米特法则

转自&#xff1a;http://my.oschina.net/shyl/blog/531542 <?phpclass Teacher {//老师对学生发布命令,清一下女生public function commond(GroupLeader $groupLeader){//初始化女生for($i0; $i<20; $i){$listGirls[] new Girl();}//告诉体育委员开始执行清查任务$grou…

【C语言简单说】十五:while循环

上一节说了for循环&#xff0c;那么我们说一下while循环&#xff1b;其实都是循环&#xff0c;就好比肯德基和徳啃鸡一样&#xff0c;卖的都是鸡~ ㄟ(▔&#xff3e;▔ㄟ) (╯▔&#xff3e;▔)╯ 上代码&#xff1a; #include<stdio.h> #include<stdlib.h> int…

我的世界java版月步教程_《我的世界》月步?幻影剑?大神才会的骚操作 第一个我就跪了!...

你知道《我的世界》玩家之间的差距有多大吗&#xff1f;“咦&#xff0c;我怎么自己动了&#xff1f;”还没看清楚自己怎么被人拉到跟前&#xff0c;敌人的钻石剑已经在方块菌身上戳出了数道伤痕。每次遇到一些操作大神&#xff0c;“佛系”玩家方块菌真的被打得找不到北&#…

剑指offer之不修改数组找出重复的数字

1 题目 不修改数组找出重复的数字 在一个长度为N1的数组里面的所有数字都在范围1~N范围内&#xff0c;所以数组至少 有一个数字是重复的&#xff0c;请找出重复数字&#xff0c;但是不能修改输入的数组。 2 思路 思路1&#xff1a; 我们开辟一个新的数组&#xff0c;初始化…

大数据能否力挽国足败落狂澜?

叙利亚多惨&#xff0c;媒体大概已经全方位铺陈过了。作为难民数量最多的国家&#xff0c;战争冲突爆发后&#xff0c;叙利亚足球联赛被迫停摆。虽然在2014年恢复了联赛的进行&#xff0c;但观众数量锐减&#xff0c;从上万到百人&#xff0c;更要直面数以百计的叙利亚球员不得…

最通俗易懂的依赖注入之服务容器与作用域

推荐关注「码侠江湖」加星标&#xff0c;时刻不忘江湖事这篇文章是 ASP.NET 6 依赖注入系列文章的第 3 篇&#xff0c;点击上方蓝字可以阅读整个系列。在上一篇文章中&#xff0c;我们讨论依赖注入的基本用法与生命周期。接下来&#xff0c;在这篇文章中&#xff0c;我们继续深…

深度学习入门(python)考试速成均方误差

均方误差 表示神经网络的输出&#xff0c;表示监督数据&#xff0c;表示数据的维度。 这里神经网络的输出y是softmax函数的输出 数组元素的索引从第一个开始依次对应数组“0”&#xff0c;“1”&#xff0c;“2”&#xff0c;...... 由于softmax函数的输出可理解为概率 由此…

C#趣味程序---理财高手

问题:假设银行存款分五种 利率:0.63% 一年 月 利率:0.66% 二年 月 利率:0.69% 三年 月 利率:0.75% 五年 月 利率:0.84% 八年 月 现在存入900000,存期为20年,问应该怎样选择,才能是本息和最大,最大为多少? 解决方案: using System;namesp…

OPENCV图像变换-1

图像变换是指将一幅图像变换为图像数据的另一种表现形式,例如将图像进行傅立叶变换,或者对图像进行X,Y方向的求导等,经过这些变换,可以将图像数据处理中的某些问题换一个别的角度想办法,所以图像变换是图像处理的时候比较常用的一种方法. 一.sobel算子 sobel算子是一个用于边缘…

postgresql select for update 多行加锁顺序_PostgreSQL和Mysql的MVCC实现机制的差异对比

任何数据库的主要要求之一就是实现可伸缩性。只有将争用&#xff08;锁定&#xff09;最小化&#xff08;如果不能一起删除&#xff09;&#xff0c;才可以实现。由于读/写/更新/删除是数据库中发生的一些主要的频繁操作&#xff0c;因此对于这些操作并发进行而不被阻塞非常重要…

【C语言简单说】十六:do...while循环

** ㄟ(▔&#xff3e;▔ㄟ) (╯▔&#xff3e;▔)╯** 今天差点忘记更了。。。 今天我们来说我们的do…while循环&#xff0c;其实这个循环和我们的while循环很像&#xff0c;区别就在于我们现在要学的这个循环是先执行一次循环&#xff0c;再去判断条件是否正确。 为什么这么…