將系統(tǒng)性能優(yōu)化到極致,永遠(yuǎn)是程序愛好者所努力的一個(gè)方向。在java并發(fā)領(lǐng)域,也有很多的實(shí)踐與創(chuàng)新,小到樂觀鎖、CAS,大到netty線程模型、纖程Quasar、kilim等。Disruptor是一個(gè)輕量的高性能并發(fā)框架,以驚人的吞吐量而受到廣泛的關(guān)注。Disruptor為提高程序的并發(fā)性能,提供了很多新的思路,比如:
緩存行填充,消除偽共享;
RingBuffer無鎖隊(duì)列設(shè)計(jì);
預(yù)分配緩存對(duì)象,使用緩存的循環(huán)覆蓋取代緩存的新增刪除等;
下文將從源碼角度解析Disruptor的實(shí)現(xiàn)原理。
1 Disruptor術(shù)語
Disruptor有很多自身的概念,使得初學(xué)者看代碼會(huì)比較費(fèi)勁。因此在深入Disruptor原理之前,需要先了解一下Disruptor主要的幾個(gè)核心類或接口。
Sequence: 采用緩存行填充的方式對(duì)long類型的一層包裝,用以代表事件的序號(hào)。通過unsafe的cas方法從而避免了鎖的開銷;
Sequencer: 生產(chǎn)者與緩存RingBuffer之間的橋梁。單生產(chǎn)者與多生產(chǎn)者分別對(duì)應(yīng)于兩個(gè)實(shí)現(xiàn)SingleProducerSequencer與MultiProducerSequencer。Sequencer用于向RingBuffer申請(qǐng)空間,使用publish方法通過waitStrategy通知所有在等待可消費(fèi)事件的SequenceBarrier;
WaitStrategy: WaitStrategy有多種實(shí)現(xiàn),用以表示當(dāng)無可消費(fèi)事件時(shí),消費(fèi)者的等待策略;
SequenceBarrier: 消費(fèi)者與緩存RingBuffer之間的橋梁。消費(fèi)者并不直接訪問RingBuffer,從而能減少RingBuffer上的并發(fā)沖突;
EventProcessor: 事件處理器,是消費(fèi)者線程池Executor的調(diào)度單元,是對(duì)事件處理EventHandler與異常處理ExceptionHandler等的一層封裝;
Event: 消費(fèi)事件。Event的具體實(shí)現(xiàn)由用戶定義;
RingBuffer: 基于數(shù)組的緩存實(shí)現(xiàn),也是創(chuàng)建sequencer與定義WaitStrategy的入口;
Disruptor: Disruptor的使用入口。持有RingBuffer、消費(fèi)者線程池Executor、消費(fèi)者集合ConsumerRepository等引用。
2 Disruptor源碼分析
2.1 Disruptor并發(fā)模型
并發(fā)領(lǐng)域的一個(gè)典型場(chǎng)景是生產(chǎn)者消費(fèi)者模型,常規(guī)方式是使用queue作為生產(chǎn)者線程與消費(fèi)者線程之間共享數(shù)據(jù)的方法,對(duì)于queue的讀寫避免不了讀寫鎖的競(jìng)爭(zhēng)。Disruptor使用環(huán)形緩沖區(qū)RingBuffer作為共享數(shù)據(jù)的媒介。生產(chǎn)者通過Sequencer控制RingBuffer,以及喚醒等待事件的消費(fèi)者,消費(fèi)者通過SequenceBarrier監(jiān)聽RingBuffer的可消費(fèi)事件??紤]一個(gè)場(chǎng)景,一個(gè)生產(chǎn)者A與三個(gè)消費(fèi)者B、C、D,同時(shí)D的事件處理需要B與C先完成。則該模型結(jié)構(gòu)如下:
在這個(gè)結(jié)構(gòu)下,每個(gè)消費(fèi)者擁有各自獨(dú)立的事件序號(hào)Sequence,消費(fèi)者之間不存在共享競(jìng)態(tài)。SequenceBarrier1監(jiān)聽RingBuffer的序號(hào)cursor,消費(fèi)者B與C通過SequenceBarrier1等待可消費(fèi)事件。SequenceBarrier2除了監(jiān)聽cursor,同時(shí)也監(jiān)聽B與C的序號(hào)Sequence,從而將最小的序號(hào)返回給消費(fèi)者D,由此實(shí)現(xiàn)了D依賴B與C的邏輯。
RingBuffer是Disruptor高性能的一個(gè)亮點(diǎn)。RingBuffer就是一個(gè)大數(shù)組,事件以循環(huán)覆蓋的方式寫入。與常規(guī)RingBuffer擁有2個(gè)首尾指針的方式不同,D