如何理解Netty的鎖,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
樺甸網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁設計、網(wǎng)站建設、微信開發(fā)、APP開發(fā)、響應式網(wǎng)站建設等網(wǎng)站項目制作,到程序開發(fā),運營維護。創(chuàng)新互聯(lián)于2013年創(chuàng)立到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設就選創(chuàng)新互聯(lián)。
原子性:“并無一氣呵成,豈能無懈可擊”,如:高并發(fā)下的 i++
可見性:“你做的改變,別人看不見”
有序性:“不按套路出牌”
競爭的態(tài)度:樂觀鎖(java.util.concurrent 包中的原子類) 與 悲觀鎖(synchronized)
等待鎖的人是否公平:公平鎖 new ReentrantLock(true) 與 非公平鎖 new ReentrantLock()
是否可共享:共享鎖 與 獨享鎖 - ReadWriteLock,其讀鎖是共享鎖,其寫鎖是獨享鎖
例:初始化 channel (io.netty.bootstrap.ServerBootstrap#init)
Synchronized method -> Synchronized block
void init(Channel channel) throws Exception { Map, Object> options = this.options0(); synchronized(options) { setChannelOptions(channel, options, logger); } Map , Object> attrs = this.attrs0(); synchronized(attrs) { Iterator var5 = attrs.entrySet().iterator(); while(true) { if (!var5.hasNext()) { break; } Entry , Object> e = (Entry)var5.next(); AttributeKey
例:統(tǒng)計待發(fā)送的字節(jié)數(shù) (io.netty.channel.ChannelOutboundBuffer)
AtomicLong -> Volatile long + AtomicLongFieldUpdater
AtomicLong vs long
前者是一個對象,包含對象頭(object header)以用來保存 hashcode、lock等信息,32 位系統(tǒng)占用 8 字節(jié),64 位系統(tǒng)占用 16 字節(jié),所以在 64 位系統(tǒng)下:
volatile long = 8 bytes
AtomicLong = 8 bytes (volatile long) + 16 bytes (object header) + 8 bytes (引用) = 32 bytes
至少節(jié)約 24 字節(jié)!
結論:
Atomic* objects -> Volatile primary type + static Atomic*FieldUpdater
原子類型的對象可以用 volatile 修飾的基礎類型來代替,以節(jié)省空間
例1:記錄內存分配字節(jié)數(shù)等功能用到的 LongCounter (io.netty.util.internal.PlatformDependent#newLongCounter())
高并發(fā)時:java.util.concurrent.atomic.AtomicLong -> java.util.concurrent.atomic.LongAdder (JDK)
結論:及時衡量,使用jdk最新功能
例2:曾經(jīng)根據(jù)不同情況,選擇不同的并發(fā)包實現(xiàn):JDK < 1.8 考慮 ConcurrentHashMapV8(ConcurrentHashMap 在 JDK8 中的版本)
例1:關閉和等待關閉事件執(zhí)行器(Event Executor):
Object.wait/notify -> CountDownLatch
io.netty.util.concurrent.SingleThreadEventExecutor#threadLock
例2:Nio Event Loop 中負責存儲 task 的 Queue
Jdk's LinkedBlockingQueue(MPMC) -> jctools' MPSC
MPMC: muti-producer & muti-consumer
MPSC: muti-producer & simple-consumer
io.netty.util.internal.PlatformDependent.Mpsc#newMpscQueue(int)
生活場景:
飯店提供了很多包廂,服務模式:
一個服務員固定服務某幾個包廂模式;
所有服務員服務所有的包廂模式;
表面上看,前者效率沒有后者高,但實際上它避免了服務員間的溝通(上下文切換)等開銷,避免客人與服務員之間導出亂串,管理簡單。
局部串行:Channel 的 I/O 請求處理 Pipeline 是串行的
整體并行:多個串行化線程(Nio Event Loop)
Netty 應用場景下:局部串行 + 整體并行 > 一個隊列 + 多個線程模式:
降低用戶開發(fā)難度、邏輯簡單、提升處理性能
避免鎖帶來的上下文切換和并發(fā)保護等額外開銷
看完上述內容,你們掌握如何理解Netty的鎖的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!