2011-11-29 107 views
4

netty文檔建議在ChannelHandlers中使用實例變量來跟蹤通道狀態。它沒有提到你應該使用volatile變量或者使用任何其他同步技術來確保跨線程有一致的視圖。在Netty ChannelHandler中保持狀態

例如,使用在每個連接的基礎這個處理程序:

class Handler extends SimpleChannelUpstreamHandler { 
     int count = 0; 

     @Override 
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { 
      ++count; 
     } 
} 

我希望從一個網狀線程池中的許多不同的線程將調用此方法,但不能同時使用,並有可能看到一個不一致的觀點,導致計數不準確。

這是這種情況?或者netty內部是否有某種同步進行,這會導致寫入計數字段的內容被刷新?

回答

6

狀態。如果你沒有在你的管道的執行,並執行你的處理程序純粹在I/O工作線程中,那麼你很好,因爲Netty保證給定的管道實例總是從同一個工作線程回調。

如果您正在向管道添加執行處理程序,那麼如果使用Netty的OrderedMemoryAwareThreadPoolExecutor,則可以。

如果您正在從非Netty線程訪問您的管道,或者您的管道中有非OrderedMemoryAwareThreadPoolExecutor,則需要同步。

我建議通過Netty用戶論壇檔案中的以下主題進行觀察。

http://netty.markmail.org/search/?q=Memory+visibility+in+handlers#query:Memory%20visibility%20in%20handlers+page:1+mid:cmtw5omcxbg67sho+state:results

http://netty.markmail.org/search/?q=Periodic%20TimerTask%20in#query:Periodic%20TimerTask%20in+page:2+mid:vwahepiois4eqwkp+state:results

+0

謝謝!這就是我所尋找的,「Netty保證給定的管道實例始終從同一個工作線程回調」 –

2

當您創建的Netty ChannelPipeline如果您添加Handler相同實例所有通道則是,多個線程將讀取/修改數據。

如果您創建的Handler每個通道在您的管道,如下圖所示,那麼你是安全的,只有一個線程將在同一時間訪問在pipeline處理程序,然後一個新的實例。

ChannelPipeline p = Channels.pipeline(); 
pipeline.addLast("handler", new Handler()); 

而且看一看的Netty ChannelLocal,它像java ThreadLocal,你可以設置每個通道的基礎

+0

權,我想,只有一個線程將永遠訪問處理器並行但dosent保證訪問的處理器將看到第一個線程所做的更改,除非第二個線程netty正在做一個易變的寫或其他保證可見性的東西 –