• 基于双向链表的简单阻塞队列


      最近工作比较忙,水一篇:

    /**
     * @Author Niuxy
     * @Date 2020/6/8 8:54 下午
     * @Description 基于双向链表的简单 FIFO 队列
     * 锁的粒度很粗,仅针对最上层操作进行互斥同步关系规划
     * 最上层方法有两个:put 与 remove
     * 以 length 与 capacity 是否相等为竞态条件进行同步
     * put 与 remove 操作涉及了相同的共享变量,动作互斥
     * 只要在某个时刻,两个动作的竞态条件必然有一个会得到满足,便至少有一个线程处于运行状态
     * 锁的设计越少越安全,但粒度太粗的互斥关系也会降低运行效率。如果锁较多,需要注意锁依赖(获取顺序)的一致性,防止死锁
     */
    public class SynchronizedQueue<T> {
    
        /**
         * @Author Niuxy
         * @Date 2020/6/8 9:01 下午
         * @Description 双向链表节点
         */
        class Node {
            private T value;
            private Node next;
            private Node pre;
    
            Node(T value) {
                this.value = value;
            }
    
            public T getValue() {
                return value;
            }
    
            public void setValue(T value) {
                this.value = value;
            }
    
            public Node getNext() {
                return next;
            }
    
            public void setNext(Node next) {
                this.next = next;
            }
    
            public Node getPre() {
                return pre;
            }
    
            public void setPre(Node pre) {
                this.pre = pre;
            }
        }
    
        // 队列容量
        private int capacity;
        // 队列当前长度
        private int length;
    
        //虚拟头结点
        private Node firstNode;
        //虚拟尾结点
        private Node lastNode;
    
        SynchronizedQueue(int capacity) {
            this.capacity = capacity;
            this.length = 0;
            firstNode = new Node(null);
            lastNode = new Node(null);
            firstNode.setNext(lastNode);
            lastNode.setPre(firstNode);
        }
    
        // 移除并返回队尾节点
        public synchronized T remove() throws InterruptedException {
            if (length == 0) {
                wait();
            }
            Node node = lastNode.pre;
            while (length <= 0) {
                throw new RuntimeException("outOfIndex:" + String.valueOf(length - capacity));
            }
            node.pre.next = lastNode;
            lastNode.pre = node.pre;
            length--;
            notifyAll();
            return node.value;
        }
    
        // 新增节点,放入队首
        public synchronized void put(T value) throws InterruptedException {
            while (length == capacity) {
                wait();
            }
            Node node = new Node(value);
            node.next = firstNode.next;
            node.pre = firstNode;
            firstNode.next = node;
            node.next.pre = node;
            length++;
            print();
            notifyAll();
        }
    
        private synchronized void print() {
            Node node = firstNode.next;
            while (node != lastNode) {
                System.out.print(node.value + ",");
                node = node.next;
            }
            System.out.println("---------");
        }
    }
  • 相关阅读:
    10个大数据领域的杰出公司
    面向对象下面几步
    $response->decoded_content; 和$response->content; 乱码问题
    netty新建连接并发数很小的case
    与eclipse集成的管理zookeeper工具
    zookeeper集群搭建
    用 Flask 来写个轻博客 (22) — 实现博客文章的添加和编辑页面
    perl 对象
    业务人员自助BI分析不够用,还要自助数据准备?
    业务人员自助BI分析不够用,还要自助数据准备?
  • 原文地址:https://www.cnblogs.com/niuyourou/p/13080329.html
Copyright © 2020-2023  润新知