JAVA并发编程有界缓存的实现详解
作者:lqh 发布时间:2022-12-09 16:12:53
标签:java,有界缓存
JAVA并发编程有界缓存的实现
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;
}
}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


猜你喜欢
- 第一种方法:获取手机的IMSI码,并判断是中国移动\中国联通\中国电信TelephonyManager telManager = (Tele
- 一. 前言最近我发现了一个事情,那就是在面试笔试中,好多公司都喜欢在String字符串上出问题,涉及到方方面面的知识,包括其中的一些常用方法
- 本文实例讲述了C#获取两个时间的时间差并去除周末的方法。分享给大家供大家参考。具体分析如下:一般来说取时间差的代码很多,但是能够只取工作日的
- 首先我们要明白一下几点,1.代码写出来除了让他跑起来还有个非常非常重要的作用是维护,因为没有一成不变的代码,需求变化代码就不可避免的要变化。
- 出于安全考虑,在后台与前台进行数据传输时,往往不会直接传输实体模型,而是使用Dto(Data transfer object 数据传输对象)
- 目录规则(来自百度百科,康威生命游戏词条)控制台实现的关键接口代码实现规则(来自百度百科,康威生命游戏词条)游戏开始时,每个细胞随机地设定为
- 示例代码如下:launch(Dispatchers.Main) { // 第一部分 fl
- 在日常工作中,我们可能需要连接多个MongoDB数据源,比如用户库user,日志库log。本章我们来记录连接多个数据源的步骤,以两个数据源为
- 目录前言1、什么叫循环依赖呢2、具体出现循环依赖的代码逻辑3、解决循环依赖的代码实现总结前言本文基于springboot版本2.5.1 &n
- 自动装配的含义在SpringBoot程序main方法中,添加@SpringBootApplication或者@EnableAutoConfi
- 一、JMeter后端 * 介绍说到JMeter后端 * ,必须要从源头BackendListener开始说,最后延伸到我们需要的Backen
- 面试题1:说说什么分布式事务?解释一下什么是CAP?现在互联网开发多使用微服务架构,一个简单的操作,在服务端可能就是由多个服务和数据库实例协
- 一开始我就纳闷了,怎么调试都只是一个光溜溜的界面,右侧的工具栏都没有如图:就一个光秃秃的界面,什么都没有,这就对调试很不方便于是我就试了试各
- WCF实例(带步骤) <xmlnamespace prefix ="o" ns ="urn:schema
- SharedPreferences用于在开发软件的时候提供软件参数设置,其背后使用的是xml文件存放数据,文件保存在/data/data/&
- 一直想练习下java多线程抓取数据。有天被我发现,铃声多多的官网(http://www.shoujiduoduo.com/main/)有大量
- 一、案例场景遇到过这样的场景,在定义一个static修饰的Map时,使用了大量的put()方法赋值,就类似这样——public static
- 在使用Gateway 调用一个文件上传服务时 前端传来的File的base64字符串怎么都接受不到 但是用Body方式请求就能接收到后来经过
- VelocityTracker顾名思义即速度跟踪,在android中主要应用于touch even。Velocit
- Intellij IDEA 最突出的功能自然是调试(Debug),可以对Java代码,JavaScript,JQuery,Ajax等技术进行