• 【JAVA并发编程实战】11、有界缓存的实现


    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;
        }
        
    }
  • 相关阅读:
    hover经过放大效果
    TDD
    VisualStudio UnitTest FrameWork
    Rhino Mock
    Unit Test
    GPS坐标转化为百度坐标
    只上传APK而不进行反编译,在服务器集成第三方SDK。是如何实现的
    如何实现滑动scrollview上下隐藏
    Windroy、Windroye、Bluestacks运行Android实现原理
    问个file的问题
  • 原文地址:https://www.cnblogs.com/cutter-point/p/6106605.html
Copyright © 2020-2023  润新知