disruptor

来源:互联网 发布:usb安装centos 编辑:程序博客网 时间:2024/05/29 10:44

1.介绍
lmax主要面向高速交易平台。Disruptor是采用JAVA开发的并行编程框架,核心为RingBuffer数据结构。通过对于常用的RingBuffer数据结构实现的分析,lmax团队重新设计了RingBuffer的实现逻辑,具体参见网站:http://code.google.com/p/disruptor/
和论文:http://disruptor.googlecode.com/files/Disruptor-1.0.pdf。测试效率高于JAVA并发框架ArrayBlockingQueue。
国内解道网站http://www.jdon.com/42466上面也有相应的介绍(他们将在自己的项目中采用了Disruptor)。
本文对于disruptor并行开发框架的使用进行介绍,随后的文章对于其架构设计进行阐述。

2.基本使用方法
在Disruptor的使用过程中,主要涉及的内容分为以下几个方面:
(1)RingBuffer设置;RingBuffer的长度,获得写入位置的方法,线程竞争写入时的等待策略等;
(2)Ringbuffer可读之后,消费线程如何处理。

3.涉及到的类和方法
RingBuffer类,创建RingBuffer对象的时候,需要指定是否为多线程操作,线程竞争时的等待策略。
主要代码:

    private final RingBuffer<StockEvent> ringBuffer =        new RingBuffer<StockEvent>(StockEvent.EVENT_FACTORY,                                   new SingleThreadedClaimStrategy(BUFFER_SIZE),  //单线程使用                                   new YieldingWaitStrategy());                   //等待策略

BatchEventProcessor类,主要实现对于ringbuffer可读之后,如何去处理。
主要代码:

 private final SequenceBarrier sequenceBarrier = ringBuffer.newBarrier(); private final BatchEventProcessor<StockEvent> batchEventProcessor =     new BatchEventProcessor<StockEvent>(ringBuffer, sequenceBarrier, handler);

EventHandler类,主要是具体处理的处理方法。
主要代码:

public void onEvent(StockEvent event, long sequence, boolean endOfBatch) throws Exception {// TODO Auto-generated method stubSystem.out.println("stock number is: " + event.getStockNumber());System.out.println("stock price is: " + event.getStockPrice());}

其中,主要是实现onEvent当ringbuffer可读时,对于buffer中的元素具体处理方法。自己程序的处理方法,需要继承该类,并实现该方法。
4.单一的生产者-消费者模式
我们已单一的生产者-消费者作为样例,生产者向Ringbuffer中写入元素后,消费者读取元素进行处理(样例中,只是输出)。
主代码:

public class Con_Pro {private static final int BUFFER_SIZE = 1024;    private final RingBuffer<StockEvent> ringBuffer =        new RingBuffer<StockEvent>(StockEvent.EVENT_FACTORY,                                   new SingleThreadedClaimStrategy(BUFFER_SIZE),                                   new YieldingWaitStrategy());    private final SequenceBarrier sequenceBarrier = ringBuffer.newBarrier();        private final StockEventHandler handler = new StockEventHandler();        private final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();        private final BatchEventProcessor<StockEvent> batchEventProcessor =     new BatchEventProcessor<StockEvent>(ringBuffer, sequenceBarrier, handler);    {        ringBuffer.setGatingSequences(batchEventProcessor.getSequence());    }        public Con_Pro() {        }        /*启动消费者线程,实际上调用了StockEventHandler中的onEvent方法进行处理*/    public void runCon() {         EXECUTOR.submit(batchEventProcessor);    }    /*单独启动一个生产者线程,向Ringbuffer中写入元素*/    public void runPro() {        new Thread(new ChgStockInfo(ringBuffer)).start();     }        public static void main(String args[]) {        Con_Pro conpro = new Con_Pro();    conpro.runCon();    conpro.runPro();    }}

生产者先获取Ringbuffer中下一个可用的slot,然后取得该slot,写入后通过publish发布。代码为:

public class ChgStockInfo implements Runnable{private RingBuffer<StockEvent> ringbuffer = null;private String proId = null;public ChgStockInfo(RingBuffer<StockEvent> rb) {ringbuffer = rb;}public ChgStockInfo(RingBuffer<StockEvent> rb, String id) {ringbuffer = rb;proId = id;}public void run() {// TODO Auto-generated method stubint number = 1;long price = 10;while(true) {//获取下一个可用的slotlong pos = ringbuffer.next();StockInfo stockInfo = new StockInfo();stockInfo.setNumber(number++);stockInfo.setPrice(++price);//获得该slotringbuffer.get(pos).setStockInfo(stockInfo);System.out.println("put the stock info into queue by: " + proId);//提交修改ringbuffer.publish(pos);try {double interval = Math.random();Thread.sleep((long) (1000 * interval));} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}

5.多生产者-但消费者模式
此时主要是在Ringbuffer创建时,需要设定不同的等待和claim策略。

    private final RingBuffer<StockEvent> ringBuffer =        new RingBuffer<StockEvent>(StockEvent.EVENT_FACTORY,                                   new MultiThreadedLowContentionClaimStrategy(BUFFER_SIZE),                                   new YieldingWaitStrategy());

启动多个产生者线程进行处理:

   public void runPro() {        for (int i = 0; i < 5; i++) {    new Thread(new ChgStockInfo(ringBuffer, Integer.toString(i))).start();    }    }

上述的eclipse项目代码为:TestDisruptor。由于刚刚接触disruptor,欢迎批评指正。

0 0
原创粉丝点击