JDK集合中的好味道

81 阅读1分钟

LinkedBlockingDeque

代码中的好味道

    /**
     * Removes and returns first element, or null if empty.
     */
    private E unlinkFirst() {
        // assert lock.isHeldByCurrentThread();
        Node<E> f = first;
        if (f == null)
            return null;
        Node<E> n = f.next;
        E item = f.item;
        f.item = null;
        f.next = f; // help GC
        first = n;
        if (n == null)
            last = null;
        else
            n.prev = null;
        --count;
        notFull.signal();
        return item;
    }

从上段代码中可以看到,临时节点f在使用完之后将f.next = f,即将下一个节点的指针指向自己。这样就不会与队列中存在的节点保持引用,那么JVM进行root扫描时候会将Node f视为垃圾进行回收,否则会出现内存泄漏的风险。

知识点

  1. ReentrantLock的使用
  2. Condition的使用 实例:
    public E takeFirst() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            E x;
            while ( (x = unlinkFirst()) == null)
                notEmpty.await();
            return x;
        } finally {
            lock.unlock();
        }
    }
    
    
  public void putFirst(E e) throws InterruptedException {
        if (e == null) throw new NullPointerException();
        Node<E> node = new Node<E>(e);
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            while (!linkFirst(node))
                notFull.await();
        } finally {
            lock.unlock();
        }
    }

因为这对方法中使用的是同一把锁的Condition,所以会让让阻塞在方法中的其他线程互相进行唤醒。