首页 > 代码库 > [Jetty9.3]-Jetty的NIO调度:ManagedSelector

[Jetty9.3]-Jetty的NIO调度:ManagedSelector

ManagedSelector是整个Jetty NIO的核心实现

  • 它是SelectorManger的内部类, 本质上封装了java.nio.channels.Selector
  • 每个ManagedSelector存在PROCESSING, SELECTING和LOCKED三种状态
  • ManagerdSelector实现了Runnable, 在run体中while一个select()函数.
  • ManagerdSelector#submit()是唯一其他对象(线程)用于提交可执行任务的函数.

ManagedSelector状态机解读

  • ManagedSelector内部通过一个AtomicReference类型的state变量解决多线程间的状态统一问题.
  • 在PROCESSING状态时, MS会处理_runChanges列表中的任务(串行的)或者处理selectedKeys
  • 如果#submit方法获得LOCKED状态, 则会往_addChanges列表中添加任务, 然后立马将状态切换到PROCESS
  • 如果#select方法获得LOCKED状态, 则尝试将_addChanges switch到_runChanges中, 然后立马将状态切换到PROCESS
  • 如果所有任务(_runChanges)都跑完了, 那么#select方法就会调用NIO的selector等待网络事件了.

ManagedSelector的Change

 1 loop: while(true) 2 { 3     State state=_state.get(); 4     switch (state) 5     { 6         case PROCESSING:     7             // We can loop on _runChanges list without lock, because only access here. 8             int size = _runChanges.size(); 9             for (int i=0;i<size;i++)10                 runChange(_runChanges.get(i));11             _runChanges.clear();
正如上边说的, 在PROCESSING状态时会将_runChanges中任务都跑一遍, 是一个for循环也就是串行的.
 1 protected void runChange(Runnable change) 2 { 3     try 4     { 5         if (LOG.isDebugEnabled()) 6             LOG.debug("Running change {}", change); 7         change.run(); 8     } 9     catch (Throwable x)10     {11         LOG.debug("Could not run change " + change, x);12     }13 }
runChange函数就没啥, 直接调Runnable的run方法, 也就是说也是同步的. 
 
ManagedSelector其实一共就这些Change, 其中就常见的就是Acceptor用于Server监听(listen)连接请求, Accept用于处理请求连接并在Selectkey上attach Jetty另外一个重要的对象:EndPoint.

 

ManagedSelectorSelecting状态图.jpg

图1 select()函数内部状态图

 

[Jetty9.3]-Jetty的NIO调度:ManagedSelector