Java併發編程十一 Disruptor框架HelloWorld

Java併發編程十一 Disruptor框架HelloWorld

1.簡介

Disruptor是一個高性能的異步處理框架,或者可以認爲是最快的消息框架(輕量的JMS),也可以認爲是一個觀察者模式的實現,或者事件監聽模式的實現。
Disruptor能夠在無鎖的情況下實現網絡的Queue併發操作。

2. Disruptor 關鍵類

RingBuffer: 被看作Disruptor最主要的組件,然而從3.0開始RingBuffer僅僅負責存儲和更新在Disruptor中流通的數據。對一些特殊的使用場景能夠被用戶(使用其他數據結構)完全替代。

Sequence: Disruptor使用Sequence來表示一個特殊組件處理的序號。和Disruptor一樣,每個消費者(EventProcessor)都維持着一個Sequence。大部分的併發代碼依賴這些Sequence值的運轉,因此Sequence支持多種當前爲AtomicLong類的特性。

Sequencer: 這是Disruptor真正的核心。實現了這個接口的兩種生產者(單生產者和多生產者)均實現了所有的併發算法,爲了在生產者和消費者之間進行準確快速的數據傳遞。

SequenceBarrier: 由Sequencer生成,並且包含了已經發布的Sequence的引用,這些的Sequence源於Sequencer和一些獨立的消費者的Sequence。它包含了決定是否有供消費者來消費的Event的邏輯。

WaitStrategy:決定一個消費者將如何等待生產者將Event置入Disruptor。

Event:從生產者到消費者過程中所處理的數據單元。Disruptor中沒有代碼表示Event,因爲它完全是由用戶定義的。

EventProcessor:主要事件循環,處理Disruptor中的Event,並且擁有消費者的Sequence。它有一個實現類是
BatchEventProcessor,包含了event loop有效的實現,並且將回調到一個EventHandler接口的實現對象。

EventHandler:由用戶實現並且代表了Disruptor中的一個消費者的接口。

Producer:由用戶實現,它調用RingBuffer來插入事件(Event),在Disruptor中沒有相應的實現代碼,由用戶實現。

WorkProcessor:確保每個sequence只被一個processor消費,在同一個WorkPool中的處理多個WorkProcessor不會消費同樣的sequence。

WorkerPool:一個WorkProcessor池,其中WorkProcessor將消費Sequence,所以任務可以在實現WorkHandler接口的worker吃間移交

LifecycleAware:當BatchEventProcessor啓動和停止時,於實現這個接口用於接收通知。

Disruptor簡單應用

1.建Event類(數據對象)

2.建立一個生產數據的工廠類,EventFactory,用於生產數據;

3.監聽事件類(處理Event數據)

4.實例化Disruptor,配置參數,綁定事件;

5.建存放數據的核心 RingBuffer,生產的數據放入 RungBuffer。

public class OrderMain {
    public static void main(String[] args) throws InterruptedException {
        //EventFactory 創建Event工廠
        EventFactory<OrderEvent> eventEventFactory = new OrderEventFactory();
        //定義RingBuffer大小 必須是2的N次方
        final int ringBufferSize = 1024;
        // 線程工廠
        ThreadFactory threadFactory = new OrderThreadFactory();
        //創建disruptor
        Disruptor<OrderEvent> disruptor = new Disruptor<OrderEvent>(eventEventFactory,ringBufferSize,threadFactory, ProducerType.SINGLE,new YieldingWaitStrategy());
        //消息的消費者
        OrderEventHandler eventHandler = new OrderEventHandler();
        //綁定消息的消費者
        disruptor.handleEventsWith(eventHandler);
        //啓動Disruptor
        disruptor.start();
        //得到RingBuffer (環形緩衝容器)
        RingBuffer<OrderEvent> ringBuffer = disruptor.getRingBuffer();
        //實現方式一
        //構建生產者 將RingBuffer傳入生產者中
        //OrderProducer orderProducer = new OrderProducer(ringBuffer);
        //實現方式二
        ////構建生產者帶事件翻譯類 將RingBuffer傳入生產者中
        OrderProducerEventTranslator orderProducerEventTranslator = new OrderProducerEventTranslator(ringBuffer);
        //生產者生產數據
        for(int i=0;i<100;i++){
            //orderProducer.newData(++i+"",new Random().nextInt(100));
            orderProducerEventTranslator.newData("1",new Random().nextInt(100));
        }

        Thread.sleep(1000);

        System.out.println("總價格"+eventHandler.countPrice);
        disruptor.shutdown();
    }
}
/**
 * 從生產者到消費者過程中所處理的數據單元。Disruptor中沒有代碼表示Event,因爲它完全是由用戶定義的。
 * Created by lyyz on 2018/5/22.
 */
public class OrderEvent {
    private String id;
    private long price;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public long getPrice() {
        return price;
    }

    public void setPrice(long price) {
        this.price = price;
    }
}
/**
 * 實現EventFactory接口 初始化時生成OrderEvent類
 * Created by lyyz on 2018/5/22.
 */
public class OrderEventFactory implements EventFactory {
    private AtomicInteger count = new AtomicInteger();

    @Override
    public Object newInstance() {
        count.incrementAndGet();
        System.out.println(this.hashCode()+   "          EventFactory newInstance method"+count.get());
        return new OrderEvent();
    }
}

/**
 * 由用戶實現並且代表了Disruptor中的一個消費者的接口。
 * Created by lyyz on 2018/5/22.
 */
public class OrderEventHandler implements EventHandler<OrderEvent> {
    public AtomicLong countPrice = new AtomicLong();
    @Override
    public void onEvent(OrderEvent orderEvent, long l, boolean b) throws Exception {
        System.out.println(orderEvent.getId()+"  "+orderEvent.getPrice());
        countPrice.addAndGet(orderEvent.getPrice());
    }
}
/**
 * Created by lyyz on 2018/5/22.
 */
public class OrderThreadFactory implements ThreadFactory {
    @Override
    public Thread newThread(Runnable r) {
        System.out.println("Thread Factory new Thread method");
        return new Thread(r);
    }
}
/**
 * 消息生產者類
 * Created by lyyz on 2018/5/22.
 */
public class OrderProducer {
    private RingBuffer<OrderEvent> ringBuffer;

    public OrderProducer(RingBuffer<OrderEvent> ringBuffer) {
        this.ringBuffer = ringBuffer;
    }
    /**
     * newData用來發布事件,每調用一次就發佈一次事件
     * 它的參數會用過事件傳遞給消費者
     */
    public void newData(String id,int price){
        //1.可以把ringBuffer看做一個事件隊列,那麼next就是得到下面一個事件槽
        long sequence = ringBuffer.next();
        //2.用上面的索引取出一個空的事件用於填充(獲取該序號對應的事件對象)
        OrderEvent orderEvent = ringBuffer.get(sequence);
        //3.設置業務數據
        orderEvent.setId(id);
        orderEvent.setPrice(price);
        //4.發佈事件
        ringBuffer.publish(sequence);
    }
}

/**
 * 消息生產者類 事件翻譯
 * Created by lyyz on 2018/5/22.
 */
public class OrderProducerEventTranslator {
    private RingBuffer<OrderEvent> ringBuffer;
    // 事件翻譯者
    private static final EventTranslatorTwoArg<OrderEvent, String,Integer> TRANSLATOR = new EventTranslatorTwoArg<OrderEvent, String, Integer>() {
        @Override
        public void translateTo(OrderEvent orderEvent, long l, String s, Integer i) {
            orderEvent.setId(s);
            orderEvent.setPrice(i);
        }
    };
    public OrderProducerEventTranslator(RingBuffer<OrderEvent> ringBuffer) {
        this.ringBuffer = ringBuffer;
    }

    /**
     * newData 發佈事件
     * @param id
     * @param price
     */
    public void newData(String id,int price) {
        //發佈事件 參數爲事件翻譯者和相應的參數
        //這種形式與上種的好處是 不用通過sequence來得到消息進行業務賦值而是將這些步驟交付TRANSLATOR的translateTo方法來進行處理,
        ringBuffer.publishEvent(TRANSLATOR, id, new Integer(price));
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章