深刻浅出 Java Concurrency (26): 并发容器 part 11 Exchanger[转]

能够在对中对元素进行配对和交换的线程的同步点。每一个线程将条目上的某个方法呈现给 exchange 方法,与伙伴线程进行匹配,而且在返回时接收其伙伴的对象。Exchanger 可能被视为 SynchronousQueue 的双向形式。java

换句话说Exchanger提供的是一个交换服务,容许原子性的交换两个(多个)对象,但同时只有一对才会成功。先看一个简单的实例模型。node

 

Exchanger

在上面的模型中,咱们假定一个空的栈(Stack),栈顶(Top)固然是没有元素的。同时咱们假定一个数据结构Node,包含一个要交换的元素E和一个要填充的“洞”Node。这时线程T1携带节点node1进入栈(cas_push),固然这是CAS操做,这样栈顶就不为空了。线程T2携带节点node2进入栈,发现栈里面已经有元素了node1,同时发现node1的hold(Node)为空,因而将本身(node2)填充到node1的hold中(cas_fill)。而后将元素node1从栈中弹出(cas_take)。这样线程T1就获得了node1.hold.item也就是node2的元素e2,线程T2就获得了node1.item也就是e1,从而达到了交换的目的。算法

算法描述就是下图展现的内容。数据结构

image

JDK 5就是采用相似的思想实现的Exchanger。JDK 6之后为了支持多线程多对象同时Exchanger了就进行了改造(为了支持更好的并发),采用ConcurrentHashMap的思想,将Stack分割成不少的片断(或者说插槽Slot),线程Id(Thread.getId())hash相同的落在同一个Slot上,这样在默认32个Slot上就有很好的吞吐量。固然会根据机器CPU内核的数量有必定的优化,有兴趣的能够去了解下Exchanger的源码。多线程

至于Exchanger的使用,在JDK文档上有个例子,讲述的是两个线程交换数据缓冲区的例子(实际上仍然能够认为是生产者/消费者模型)。并发

class FillAndEmpty {
   Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>();
   DataBuffer initialEmptyBuffer =   a made-up type
   DataBuffer initialFullBuffer = 

   class FillingLoop implements Runnable {
     public void run() {
       DataBuffer currentBuffer = initialEmptyBuffer;
       try {
         while (currentBuffer != null) {
           addToBuffer(currentBuffer);
           if (currentBuffer.isFull())
             currentBuffer = exchanger.exchange(currentBuffer);
         }
       } catch (InterruptedException ex) {   handle   }
     }
   }

   class EmptyingLoop implements Runnable {
     public void run() {
       DataBuffer currentBuffer = initialFullBuffer;
       try {
         while (currentBuffer != null) {
           takeFromBuffer(currentBuffer);
           if (currentBuffer.isEmpty())
             currentBuffer = exchanger.exchange(currentBuffer);
         }
       } catch (InterruptedException ex) {   handle  }
     }
   }

   void start() {
     new Thread(new FillingLoop()).start();
     new Thread(new EmptyingLoop()).start();
   }
  }

 

Exchanger实现的是一种数据分片的思想,这在大数据状况下将数据分红必定的片断而且多线程执行的状况下有必定的使用价值。oop

最近一直推托工做忙,更新频度愈来愈低了,好在如今的工做还有点我的时间,之后争取多更新下吧,至少也要把这个专辑写完。大数据

相关文章
相关标签/搜索