当前位置: 移动技术网 > IT编程>开发语言>Java > JAVA并发编程有界缓存的实现详解

JAVA并发编程有界缓存的实现详解

2019年07月22日  | 移动技术网IT编程  | 我要评论

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;
  }
  
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网