NioEventLoopGroup繼承層次結構圖

NioEventLoopGroup繼承層次結構圖

Netty4的NioEventLoopGroup繼承結構很複雜,爲了理解它如何工做,我畫了一張相似UML的圖。可是這張圖也很巨大,因此我作了如下處理:html

  • 將位於不一樣中的類或接口用不一樣的顏色加以區分

  • 接口名後面的括號裏標註了大寫字母I(Interface),抽象類名的後面標註了大寫字母A(Abstract)

  • 每一個類或接口,只列出了我認爲最重要的一個方法

 

EventExecutorGroup

首先從EventExecutorGroup開始,EventExecutorGroup是NioEventLoopGroup最上層的接口,再往上就是Java的地盤了:java

 

從上面的圖能夠看出3點:api

  1. EventExecutorGroup接口繼承了java.util.concurrent.ScheduledExecutorService接口,所以它能夠調度執行task
  2. EventExecutorGroup內部管理了n個EventExecutornext()方法返回其中的一個
  3. EventExecutor也是EventExecutorGroup(的子類)

想象一下,EventExecutorGroup就像一個BOSS,每當有活兒的時候,就派一個小弟(EventExecutor)去幹:數組

 

AbstractEventExecutorGroup

AbstractEventExecutorGroup抽象類實現了ScheduledExecutorService接口,但大部分實現都只是調用next()拿到一個EventExecutor,而後調用EventExecutor的相應方法,例如submit()方法:promise

 

[java] view plain copy多線程

 在CODE上查看代碼片派生到個人代碼片

  1. public abstract class AbstractEventExecutorGroup implements EventExecutorGroup {  
  2.   
  3.     @Override  
  4.     public Future<?> submit(Runnable task) {  
  5.         return next().submit(task);  
  6.     }  
  7.     ...  
  8. }  

 

 

 

MultithreadEventExecutorGroup

從類名來看,MultithreadEventExecutorGroup有並行(多線程)分配小弟去幹活的能力,換句話說,每一個小弟都工做在本身的線程中。從代碼中也能看出這一點:app

 

[java] view plain copyide

 在CODE上查看代碼片派生到個人代碼片

  1. public abstract class MultithreadEventExecutorGroup extends AbstractEventExecutorGroup {  
  2.   
  3.     private final EventExecutor[] children;  
  4.     private final AtomicInteger childIndex = new AtomicInteger();  
  5.     private final AtomicInteger terminatedChildren = new AtomicInteger();  
  6.     private final Promise<?> terminationFuture = new DefaultPromise(GlobalEventExecutor.INSTANCE);  
  7.   
  8.     protected MultithreadEventExecutorGroup(int nThreads, ThreadFactory threadFactory, Object... args) {  
  9.         ...  
  10.         children = new SingleThreadEventExecutor[nThreads];  
  11.         ...  
  12.     }  
  13.   
  14.     ...  
  15. }  

能夠看出,MultithreadEventExecutorGroup的每個小弟都是一個SingleThreadEventExecutor,並且小弟的數量在構造的時候就肯定了,以下圖所示:oop

 

 

 

從MultithreadEventExecutorGroup的next()方法能夠看到,這個BOSS的小弟分配邏輯至關簡單,無非就是輪流使喚:spa

 

[java] view plain copy

 在CODE上查看代碼片派生到個人代碼片

  1. @Override  
  2. public EventExecutor next() {  
  3.     return children[Math.abs(childIndex.getAndIncrement() % children.length)];  
  4. }  

注:這裏調用了Math.abs()方法以防止childIndex溢出

 

 

MultithreadEventLoopGroup

MultithreadEventLoopGroup類實現了EventLoopGroup接口和register()方法:

 

[java] view plain copy

 在CODE上查看代碼片派生到個人代碼片

  1. public abstract class MultithreadEventLoopGroup extends MultithreadEventExecutorGroup implements EventLoopGroup {  
  2.     ...  
  3.       
  4.     @Override  
  5.     public ChannelFuture register(Channel channel) {  
  6.         return next().register(channel);  
  7.     }  
  8.   
  9.     @Override  
  10.     public ChannelFuture register(Channel channel, ChannelPromise promise) {  
  11.         return next().register(channel, promise);  
  12.     }  
  13. }  

 

 

NioEventLoopGroup

最後是NioEventLoopGroup,這個BOSS的每個小弟都是一個NioEventLoop。下面是完整的繼承層次結構圖:

 

結論

  • NioEventLoopGroup實際上就是個線程池
  • NioEventLoopGroup在後臺啓動了n個NioEventLoop來處理Channel事件
  • 每個NioEventLoop負責處理m個Channel
  • NioEventLoopGroup從NioEventLoop數組裏挨個取出NioEventLoop來處理Channel

相關文章
相關標籤/搜索