Disruptor-02 再探

2020-06-09  本文已影响0人  rock_fish
上期回顾

Disruptor-01 初识中对Disruptor有了初步的认知,大概知道其核心组成元素以及核心运转流程,在所有的组成元素中,EventFactory作用不甚清晰,这一篇就来弄清楚EventFactory的作用。

EventFactory什么时候用

我们在代码中,加入一些日志信息

public class LongEventFactory implements EventFactory<LongEvent>
{
    public LongEvent newInstance()
    {

        LongEvent longEvent =  new LongEvent();
        System.out.println("new Event:" + longEvent.hashCode());
        return  longEvent;
    }
}
     public static void main(String[] args) throws InterruptedException {

        // Executor that will be used to construct new threads for consumers
        Executor executor = Executors.newCachedThreadPool();

        // 事件工厂,用于创建event
        LongEventFactory factory = new LongEventFactory();

        // 指定ringbuf的大小,必须是2的整数倍
        int bufferSize = 4;

        // 构建一个 Disruptor
        Disruptor<LongEvent> disruptor = new Disruptor<>(factory, bufferSize, executor);

        System.out.println("..new Disruptor...");
        // 给disruptor中添加消费者
        disruptor.handleEventsWith(new LongEventHandler());
        System.out.println("..handleEventsWith...");
        // 启动disruptor
        disruptor.start();
        System.out.println("..start...");

        //-----------万事俱备,只欠消息(消息的生产者投递消息)

        // Get the ring buffer from the Disruptor to be used for publishing.
        RingBuffer<LongEvent> ringBuffer = disruptor.getRingBuffer();

        LongEventProducer producer = new LongEventProducer(ringBuffer);

        // 跟blockqueue 比对一下

        for (long l = 0; l<12; l++)
        {
            long startAt = System.currentTimeMillis();
            producer.publishEvent(l);
            long endAt = System.currentTimeMillis();
            //System.out.println(endAt-startAt);
            //Thread.sleep(1000);
        }
    }
new Event:801197928
new Event:1495242910
new Event:1711574013
new Event:1631862159
..new Disruptor...
..handleEventsWith...
..start...

通过以上日志信息,可明确在构建Disruptor的时候,会调用LongEventFactory#newInstance创建对象,队列多大,就预先创建多少个事件对象.

此时我们的疑问是,这里预先创建这些对象什么作用呢?

生产者重复使用预创建的事件对象

通过以下日志信息可以看出,事件对象再循环反复使用;

801197928
1495242910
1711574013
1631862159
----------------LongEvent{value=0}
----------------LongEvent{value=1}
----------------LongEvent{value=2}
----------------LongEvent{value=3}
801197928
1495242910
1711574013
1631862159
----------------LongEvent{value=4}
----------------LongEvent{value=5}
----------------LongEvent{value=6}
----------------LongEvent{value=7}

同时我们会开始留意translateTo这个方法的作用是,复用对象,仅变更对象中的属性值.

/**
 * 复用对象,仅变更对象中的属性值
 */
public class LongEventTranslator  implements EventTranslatorOneArg<LongEvent,Long> {
    @Override
    public void translateTo(LongEvent longEvent, long l, Long aLong) {
        System.out.println(longEvent.hashCode());
        longEvent.set(aLong);
    }
}java

方法中关键逻辑是 通过longEvent.set(aLong),将消息内容aLong赋值给longEvent中的long类型变量.

为什么要预创建对象,为什么要复用这些事件对象
  1. 避免对象的创建和销毁
    1.1 减少空间开销(内存)
    1.2 减少时间开销(new,GC的时间消耗)
  2. 连续的创建对象,会将对象放置在一段相对连续的内存空间中
    2.1 连续内存空间的读写,效率更高
上一篇下一篇

猜你喜欢

热点阅读