JUC源码分析-集合篇(九)SynchronousQueue

JUC源码分析-集合篇(九)SynchronousQueue

JDK8 的并发编程包中的 SynchronousQueue 是一个没有数据缓冲的 BlockingQueue,生产者线程对其的插入操作 put 必须等待消费者的移除操作 take,反过来也一样。

SynchronousQueue 可以看成是一个传球手,负责把生产者线程处理的数据直接传递给消费者线程。队列本身并不存储任何元素,非常适合传递性场景。SynchronousQueue 的吞吐量高于 LinkedBlockingQueue 和 ArrayBlockingQueue。

1. SynchronousQueue 实现原理

SynchronousQueue 实现原理参考:http://ifeve.com/java-synchronousqueue/

1.1 阻塞算法实现

阻塞算法实现通常在内部采用一个锁来保证多个线程中的 put() 和 take() 方法是串行执行的。采用锁的开销是比较大的,还会存在一种情况是线程 A 持有线程 B 需要的锁,B 必须一直等待 A 释放锁,即使 A 可能一段时间内因为 B 的优先级比较高而得不到时间片运行。所以在高性能的应用中我们常常希望规避锁的使用。

public class NativeSynchronousQueue<E> {
    boolean putting = false;
    E item = null;

    public synchronized E take() throws InterruptedException {
        while (item == null)
            wait();
        E e = item;
        item = null;
        notifyAll();
        return e;
    }

    public synchronized void put(E e) throws InterruptedException {
        if (e==null) return;
        while (putting)
            wait();
        putting = true;
        item = e;
        notifyAll();
        while (item!=null)
            wait();
        putting = false;
        notifyAll();
    }
}

1.2 信号量实现

经典同步队列实现采用了三个信号量,代码很简单,比较容易理解:

public class SemaphoreSynchronousQueue<E> {
    E item = null;
    Semaphore sync = new Semaphore(0);
    Semaphore send = new Semaphore(1);
    Semaphore recv = new Semaphore(0);

    public E take() throws InterruptedException {
        recv.acquire();
        E x = item;
        sync.release();
        send.release();
        return x;
    }

    public void put (E x) throws InterruptedException{
        send.acquire();
        item = x;
        recv.release();
        sync.acquire();
    }
}

2. SynchronousQueue 实现原理

SynchronousQueue 支持公平访问队列。默认情况下线程采用非公平性策略访问队列。使用以下构造方法可以创建公平性访问的 SynchronousQueue,如果设置为 true,则等待的线程会采用先进先出的顺序访问队列。以 TransferQueue 为例

TransferQueue数据结构

参考:

  1. JUC源码分析-集合篇(九)SynchronousQueue
  2. JUC源码分析-集合篇(九)SynchronousQueue
  3. JUC源码分析-集合篇(九)SynchronousQueue

每天用心记录一点点。内容也许不重要,但习惯很重要!

猜你喜欢

转载自www.cnblogs.com/binarylei/p/10927767.html