Disruptor的使用(五)

140 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情

Disruptor的概念和初始化我们已经说差不多了,很浅,不过也该看看项目上是怎么使用的了, 前面的初始化既然创建了,那我们和使用对象一样需要获取该对象;

我们是线程池里的传参,所以可直接取到,然后获取它的环形缓冲区getRingBuffer(),在读取环形缓冲区并发布序列的过程中我们需要进行加锁操作

Lock lock = new ReentrantLock();

 通过Long sequence = ringBuffer.next();获取环形缓冲区的下一个序列返回的是Long类型,通过ringBuffer.get(sequence);获取 RingBuffer 中给定序列的空的事件。并填充相应的数据 官方注释是:此调用有 2 个用途。**第一是在发布到环形缓冲区时首先使用此调用,在调用next()之后使用此调用来获取预先分配的事件以在调用publish(long)之前填充数据**

**第二个在使用环形缓冲区中的数据时使用此调用。在调用SequenceBarrier.waitFor(long)后,使用大于您当前消费者序列且小于或等于从SequenceBarrier.waitFor(long)方法返回的值的任何值调用此方法(就是插入和读取)**

 获取序列的事件后对事件插入对应的数据,然后将该sequence序列publish上去,ringBuffer.publish(sequence);要注意的是在你发布事件(发布事件的时候要使用try/catch/finnally保证事件一定会被发布)。 如果我们使用RingBuffer.next()获取一个事件序列,那么一定要发布对应的事件,不然会引发一系列问题,最后切记别忘啦释放锁; 

Lock lock = new ReentrantLock();
lock.lock();try {    
RingBuffer<xxxEvent> ringBuffer = xxxDisruptor.getRingBuffer();  
  final long sequence = ringBuffer.next();
    xxxEvent xmEvent = ringBuffer.get(sequence);   
 xmEvent.setData(resultData);      ringBuffer.publish(sequence);
} 
catch (Exception e) {   
 LOGGER.error("上传有异常", e);
} finally {    
lock.unlock();
}

在publish后做了什么操作呢,还记得我们初始化的时候的事件处理器吗,就是调用handleEventsWithWorkerPool里的事件处理器参数,在我们发布的时候它会将事件在处理器执行, 上讲说了,我们的事件处理器是向文本文件写入内容以此便达到了分析插入数据,处理数据的目的;

 网上看到一句话:使用Disruptor,主要用于对性能要求高、延迟低的场景,它通过“榨干”机器的性能来换取处理的高性能。