package cn.study.concurrency.ch14;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* 使用condition作为挂起线程的信号
* 这个是先进先出的队列
* @author xiaof
*
* @param <T>
*/
public class ConditionBoundedBuffer<T> {
protected final Lock lock = new ReentrantLock();
//数据队列长度
private static final int BUFFER_SIZE = 1024;
//建立两个condition,一个代表不为空,一个代表不满
private final Condition notFull = lock.newCondition();
private final Condition notEmpty = lock.newCondition();
private final T[] items = (T[]) new Object[BUFFER_SIZE];
private int tail, head, count; public void put(T x) throws InterruptedException
{
lock.lock();//这里在进行操作的时候上锁
try {
while(count == items.length)
{
//如果是满的就挂起线程,等待变为notFull
notFull.await();
}
items[tail] = x;
//判断是否是已经达到了满队列的情况
if(++tail == items.length)
tail = 0;
//计数值++
++count;
//插入数据,队列肯定不是空的,那么进行非空信号发布
notEmpty.signal();
} finally{
//执行完毕,切记一定要解锁
lock.unlock();
}
} //获取数据,阻塞直到队列中有数据为止
public T take() throws InterruptedException
{
lock.lock();//进行操作之前,先上锁 try {
while(count == 0)
{
//如果队列中没有数据,那么就要进行现场挂起
notEmpty.await();
}
//得到数据,用来返回
T t = items[head];
items[head] = null;//吧输出出去的数据设为空
if(++head == items.length)
head = 0; //重置队里索引
--count; //计数减一
notFull.signal();//唤醒插入操作,因为获取出去一个数据,那么队列就一定有空位
return t;
} finally {
//切记在执行完毕之后,不论成功与否,都要解锁
lock.unlock();
}
} }

【JAVA并发编程实战】12、使用condition实现多线程下的有界缓存先进先出队列的更多相关文章

  1. java并发编程实战学习(3)--基础构建模块

    转自:java并发编程实战 5.3阻塞队列和生产者-消费者模式 BlockingQueue阻塞队列提供可阻塞的put和take方法,以及支持定时的offer和poll方法.如果队列已经满了,那么put ...

  2. 【Java并发编程实战】----- AQS(四):CLH同步队列

    在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...

  3. 【Java并发编程实战】-----“J.U.C”:CyclicBarrier

    在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么 ...

  4. 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock

    ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...

  5. 【Java并发编程实战】-----“J.U.C”:ReentrantLock之一简介

    注:由于要介绍ReentrantLock的东西太多了,免得各位客官看累,所以分三篇博客来阐述.本篇博客介绍ReentrantLock基本内容,后两篇博客从源码级别分别阐述ReentrantLock的l ...

  6. 《Java并发编程实战》读书笔记一 -- 简介

    <Java并发编程实战>读书笔记一 -- 简介 并发的历史 并发的历史,也是人类利用有限的资源去提高生产效率的一个的例子. 设想现在有台计算机,这台计算机具有以下的资源: 单核CPU一个 ...

  7. 【Java并发编程实战】—– AQS(四):CLH同步队列

    在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形. 其主要从双方面进行了改造:节点的结构与节点等待机制.在结构上引入了 ...

  8. Java并发编程实战 02Java如何解决可见性和有序性问题

    摘要 在上一篇文章当中,讲到了CPU缓存导致可见性.线程切换导致了原子性.编译优化导致了有序性问题.那么这篇文章就先解决其中的可见性和有序性问题,引出了今天的主角:Java内存模型(面试并发的时候会经 ...

  9. Java并发编程实战 04死锁了怎么办?

    Java并发编程文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 前提 在第三篇 ...

随机推荐

  1. Redis学习笔记~目录

    回到占占推荐博客索引 百度百科 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合). ...

  2. python 日期计算案例

    一.计算两个日期内的所有月 def get_month_interval(start_str, end_str): start_year, start_month = list(map(int, st ...

  3. 【Win 10应用开发】如何知道UAP在哪个平台上运行

    面向22世纪的现代化应用程序可以同时在多种设备上运行,于是有朋友会有一个疑问:有时候,我们还真的需要判断一下,UAP应用程序在哪个平台上运行.尽管大多情况下我们不必要这样做,但某些特殊情况还得考虑.比 ...

  4. sizzle分析记录:分解流程

    <form> <label>Name:</label> <input name="name" /> <fieldset> ...

  5. 深入学习jQuery选择器系列第六篇——过滤选择器之状态选择器

    × 目录 [1]焦点状态 [2]哈希状态 [3]动画状态[4]显隐状态 前面的话 过滤选择器的内容非常多,本文介绍过滤选择器的最后一部分——状态选择器 焦点状态 :focus :focus选择器选择当 ...

  6. 基于Fragment的百度地图框架的使用

    博客:http://blog.csdn.net/developer_jiangqq (一)基本介绍(Fragment和SupportMapFragment): Fragment的使用现在安卓APP开发 ...

  7. 远程管理 KVM 虚机 - 每天5分钟玩转 OpenStack(5)

    上一节我们通过 virt-manager 在本地主机上创建并管理 KVM 虚机.其实 virt-manager 也可以管理其他宿主机上的虚机.只需要简单的将宿主机添加进来 填入宿主机的相关信息,确定即 ...

  8. 基于keepalived搭建MySQL的高可用集群

    MySQL的高可用方案一般有如下几种: keepalived+双主,MHA,MMM,Heartbeat+DRBD,PXC,Galera Cluster 比较常用的是keepalived+双主,MHA和 ...

  9. 初试JqueryEasyUI(附Demo)

    写在前面 准备 布局Layout 菜单树Tree 内容页Tabs 右键菜单Menu 表单Form 对话框Dialog 示例Demo下载 关于easyui不多说,对于我们这样没有美术功底的程序员来说,简 ...

  10. 千呼万唤始出来:Apache Spark2.0正式发布

    我们很荣幸地宣布,自7月26日起Databricks开始提供Apache Spark 2.0的下载,这个版本是基于社区在过去两年的经验总结而成,不但加入了用户喜爱的功能,也修复了之前的痛点. 本文总结 ...