org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor
以下所有源碼均在此類中
首先我們看下log4j2異步隊列的初始化

從這里面我們可以看到,使用的是單例的線程池,這里請注意,這個線程池里定義的是后台線程

並且對於線程池的實現我們不可以自定義配置,是寫死的,為什么要這樣做呢?原因是為了保證日志的順序性.

而在stop()方法也就是服務關閉的處理邏輯里,將循環條件設置為(隊列不為空&&次數<200次),每次則將線程休眠50毫秒,為什么要這樣做呢?這是為了拖延jvm的關閉,因為我們的線程池使用的是后台線程,所以刷日志線程也不會延長jvm的生命周期,因此需要一個前台線程保證jvm不會馬上關閉
說完這個,再說說Discuptor那邊的消費者阻塞策略,因為消費者並不是直接操作RingBuffer的,而是通過ConsumerBarrier對象間接地操作RingBuffer。像生產者一樣,Consumer要知道它的下一個讀取需要才能讀取。Consumer並不是一個個地讀取數據,而是批量讀取,舉個栗子:如果它處理完了6號slot以前的數據,那么接下來它期待處理7號slot。ConsumerBarrier返回RingBuffer的最大可訪問序號,假如是10。如果7號以后的slot還沒有數據,那么它會根據ConsumerBarrier里面的WaitStrategy策略進行等待,直到生產者生產完數據。同時,生產者每次生產完一個數據之后都會通知Consumer,而不是Consumer每次都去詢問。直到生產完10號slot的數據之后,Consumer才會一次性讀取幾個slot的數據,然后才更新自己的cursor。
它們分別是
Block:阻塞等待
Timeout: 使用LockSupport的parkNanos()方法來睡眠,好處是在睡眠的時候不會浪費CPU,壞處是因為是定時睡眠,所以會導致延遲較大
Yield: 空轉調用Thread.yield(),讓出CPU資源給其它線程,但是自己依然會去搶時間片,這個是最及時的
Sleep: 是一種混合方式,先開始spin(CPU空轉),之后沒有就緒就 Thread.yield(),在之后就會block,這個算是最佳方案吧
關於這個如何設置

根據源碼分析到要在classpath下建立一個這個名字的文件,然后寫上這樣的屬性

如下圖:

我們再說說隊列滿的情況下的拒絕策略吧

就是這三種,第一種的意思是,繼續異步線程調用排隊,第二種的意思是,阻塞當前線程等待,第三種就是丟棄
我們可以這樣子指定

或者按照官網說的這樣做就行

