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.
图1 select()函数内部状态图
时间: 2024-10-14 18:30:03