1、有界缓存的基类

package cn.xf.cp.ch14;

/**
*
*功能:有界缓存实现基类
*时间:下午2:20:00
*文件:BaseBoundedBuffer.java
*@author Administrator
*
* @param <V>
*/
public class BaseBoundedBuffer<V>
{
private final V[] buf;
private int tail;
private int head;
private int count; public BaseBoundedBuffer(int capacity)
{
//初始化数组
this.buf = (V[]) new Object[capacity];
} //放入一个数据,final方法无法被重写
protected synchronized final void doPut(V v)
{
buf[tail] = v;
if(++tail == buf.length)
{
tail = 0;
}
//插入一个方法,总量++
++count;
} /**
* 取出一个数据
* @return
*/
protected synchronized final V doTake()
{
V v = buf[head];
buf[head] = null;
if(++head == buf.length)
{
head = 0;
}
--count;
return v;
} //通过对count的判断,来确定数组是否是满的
public synchronized final boolean isFull()
{
return count == buf.length;
} public synchronized final boolean isEmpty()
{
return count == 0;
}
}

2、判定前提条件再执行操作

package cn.xf.cp.ch14;

/**
*
*功能:对插入和获取元素操作进行先行检查,然后执行操作,校验不通过不予操作
*时间:下午2:33:41
*文件:GrumpyBoundedBuffer.java
*@author Administrator
*
* @param <V>
*/
public class GrumpyBoundedBuffer<V> extends BaseBoundedBuffer<V>
{ public GrumpyBoundedBuffer(int size)
{
super(size);
} public synchronized void put(V v) throws Exception
{
//如果是满的队列,就无法插入新的元素
if(this.isFull())
{
throw new Exception("队列超出");
}
this.doPut(v);
} //同理,队列为空的就无法取出新的元素
public synchronized V take() throws Exception
{
if(this.isEmpty())
{
throw new Exception("队列中无元素");
} return this.doTake();
} }

3、通过轮询与休眠来实现简单的阻塞

package cn.xf.cp.ch14;

/**
*
*功能:通过轮询与休眠来实现简单的阻塞
*时间:下午2:55:54
*文件:SleepyBoundedBuffer.java
*@author Administrator
*
* @param <V>
*/
public class SleepyBoundedBuffer<V> extends BaseBoundedBuffer<V>
{
//2s
private static final long SLEEP_GRANULARITY = 2000; public SleepyBoundedBuffer(int capacity)
{
super(capacity);
} //放入队列的时候
public void put(V v) throws InterruptedException
{
while(true)
{
//这里不对循环上锁,不然这个锁就无法释放了,不对休眠上锁,休眠上锁,在休眠的时候别人也无法操作,永远都不可能有元素出去
synchronized (this)
{
//如果队列不是满的,那么就放入元素
if(!this.isFull())
{
this.doPut(v);
return;
}
}
//否则休眠,退出cpu占用
Thread.sleep(SLEEP_GRANULARITY);
}
} public V take() throws InterruptedException
{
while(true)
{
//这里不对循环上锁,不然这个锁就无法释放了,不对休眠上锁,休眠上锁,在休眠的时候别人也无法操作,永远都不可能有新的元素进来
synchronized(this)
{
//如果数组部位空,那么就可以取出数据
if(!this.isEmpty())
{
return this.doTake();
}
//如果队列为空,休眠几秒再试
}
Thread.sleep(SLEEP_GRANULARITY);
}
} }

4、条件队列

package cn.xf.cp.ch14;

/**
*
*功能:使用条件队列
*时间:下午3:32:04
*文件:BoundedBuffer.java
*@author Administrator
*
* @param <V>
*/
public class BoundedBuffer<V> extends BaseBoundedBuffer<V>
{ public BoundedBuffer(int capacity)
{
super(capacity);
} /**
* 放入数据元素
* @param v
* @throws InterruptedException
*/
public synchronized void put(V v) throws InterruptedException
{
while(this.isFull())
{
//这里挂起程序,会释放锁
this.wait();
}
//如果队列不为满的,那么程序被唤醒之后从新获取锁
this.doPut(v);
//执行结束,唤醒其他队列
this.notifyAll();
} public synchronized V take() throws InterruptedException
{
while(this.isEmpty())
{
this.wait();
}
V v = this.doTake();
this.notifyAll();
return v;
} }

【JAVA并发编程实战】11、有界缓存的实现的更多相关文章

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

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

  2. 《Java并发编程实战》/童云兰译【PDF】下载

    <Java并发编程实战>/童云兰译[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062521 内容简介 本书深入浅出地介绍了Jav ...

  3. java并发编程实战《二》java内存模型

    Java解决可见性和有序性问题:Java内存模型 什么是 Java 内存模型? Java 内存模型是个很复杂的规范,可以从不同的视角来解读,站在我们这些程序员的视角,本质上可以理解为, Java 内存 ...

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

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

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

    信号量Semaphore是一个控制访问多个共享资源的计数器,它本质上是一个"共享锁". Java并发提供了两种加锁模式:共享锁和独占锁.前面LZ介绍的ReentrantLock就是 ...

  6. Java并发编程实战---第六章:任务执行

    废话开篇 今天开始学习Java并发编程实战,很多大牛都推荐,所以为了能在并发编程的道路上留下点书本上的知识,所以也就有了这篇博文.今天主要学习的是任务执行章节,主要讲了任务执行定义.Executor. ...

  7. 那些年读过的书《Java并发编程实战》和《Java并发编程的艺术》三、任务执行框架—Executor框架小结

    <Java并发编程实战>和<Java并发编程的艺术>           Executor框架小结 1.在线程中如何执行任务 (1)任务执行目标: 在正常负载情况下,服务器应用 ...

  8. 《Java并发编程实战》文摘

    更新时间:2017-06-03 <Java并发编程实战>文摘,有兴趣的朋友可以买本纸质书仔细研究下. 一 线程安全性 1.1 什么是线程安全性 当多个线程访问某个类时,不管运行时环境采用何 ...

  9. Java并发编程实战 01并发编程的Bug源头

    摘要 编写正确的并发程序对我来说是一件极其困难的事情,由于知识不足,只知道synchronized这个修饰符进行同步. 本文为学习极客时间:Java并发编程实战 01的总结,文章取图也是来自于该文章 ...

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

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

随机推荐

  1. Ubuntu系统字体安装

    用惯了Windows,刚转到Ubuntu时总感觉字体显示没那么亲切,尤其是中文字体,在网页上显示特别怪.有些软件对中文字体的支持也不好,WebStorm中的Git logs中文也显示乱码.把系统语言设 ...

  2. Java中Eclipse的使用

    Eclipse是跨平台的自由集成开发环境(IDE),初衷主要为Java语言的定制.第一次使用就喜欢上了它.它可以帮我们导入包,而不需要我们导入,有很多快捷键提供我们使用,方便节省时间:最值得我喜欢的是 ...

  3. KnockoutJS 3.X API 第六章 组件(3) 组件绑定

    组件绑定将指定的组件注入到元素中,并且可选地将参数传递给它. 本节目录 一个例子 API 组件生命周期 备注1:仅限模板组件 备注2:使用没有容器元素的组件 备注3:将标记传递给组件 处置和内存管理 ...

  4. KnockoutJS 3.X API 第六章 组件(2) 组件注册

    要使Knockout能够加载和实例化组件,必须使用ko.components.register注册它们,从而提供如此处所述的配置. 注意:作为替代,可以实现一个自定义组件加载器(自定义加载器下一节介绍 ...

  5. OGNL相关代码

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  6. 元素绝对定位以后设置了高宽,a标签不能点击的原因总结

    元素绝对定位以后设置了高宽,a标签不能点击的原因: 1.元素内并无内容 2.背景是透明的,无任何背景图或者颜色 解决方法: 1.如果不是绝对定位元素的,可以用相对定位 2.给元素加透明的背景图 3.I ...

  7. LINQ系列:Linq to Object限制操作符

    1. Where 限制操作符Where用于过滤序列,按照提供的逻辑对序列中的数据进行过滤.Where可以出现多次. 1.1 原型定义 public static IEnumerable<TSou ...

  8. 解密jQuery事件核心 - 自定义设计(三)

    接上文http://www.cnblogs.com/aaronjs/p/3447483.html 本文重点:自定义事件 “通过事件机制,可以将类设计为独立的模块,通过事件对外通信,提高了程序的开发效率 ...

  9. MVC中处理表单提交的方式(使用html扩展方法+juqery插件)

    这里使用扩展方法来扩展基于jquery.form 插件,实现基于异步的ajax的提交方式.

  10. 如何高效地向Redis插入大量的数据

    最近有个哥们在群里问,有一个日志,里面存的是IP地址(一行一个),如何将这些IP快速导入到Redis中. 我刚开始的建议是Shell+redis客户端. 今天,查看Redis官档,发现文档的首页部分( ...