zoukankan      html  css  js  c++  java
  • 基于双向链表的简单阻塞队列

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

    /**
     * @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("---------");
        }
    }
  • 相关阅读:
    【转】如何高效地阅读技术类书籍与博客
    测试站点大全
    【转】软件测试面试- 购物车功能测试用例设计
    div+css 定位浅析
    C# Enum,Int,String的互相转换
    sqlserver 空间数据类型
    系统学习sqlserver2012 一
    sql查询数据库中所有表的记录条数,以及占用磁盘空间大小。
    linux网站推荐
    匿名用户访问sharepoint2010中的列表
  • 原文地址:https://www.cnblogs.com/niuyourou/p/13080329.html
Copyright © 2011-2022 走看看