el.SEVERE, Level.FINE);
} catch (Throwable t) {
logger.log(Level.SEVERE,"doSelect exception", t);
transport.notifyException(Severity.FATAL, t);
}
return true;
}
nio框架中的多个Selector结构(4)
时间:2010-12-19 BlogJava dennis
基本上是一个reactor实现的样子,在AbstractNIOTransport类维护了一个 SelectorRunner的数组,而Grizzly 用于创建tcp server的类TCPNIOTransport 正是继承于AbstractNIOTransport类,在它的start方法中调用了 startSelectorRunners来创建并启动SelectorRunner数组:
private static final int DEFAULT_SELECTOR_RUNNERS_COUNT = 2;
@Override
public void start() throws IOException {
if (selectorRunnersCount <= 0) {
selectorRunnersCount = DEFAULT_SELECTOR_RUNNERS_COUNT;
}
startSelectorRunners();
}
protected void startSelectorRunners() throws IOException {
selectorRunners = new SelectorRunner [selectorRunnersCount];
synchronized(selectorRunners) {
for (int i = 0; i < selectorRunnersCount; i++) {
SelectorRunner runner =
new SelectorRunner(this, SelectorFactory.instance().create());
runner.start();
selectorRunners[i] = runner;
}
}
}
可见Grizzly并没有采用一个单独的池对象来管理SelectorRunner,而是直接 采用数组管理,默认数组大小是2。 SelectorRunner实现了Runnable接口,它的 start方法调用了一个线程池来运行自身。刚才我提到了说Grizzly的Accept 是 单独一个Selector来管理的,那么是如何表现的呢?答案在 RoundRobinConnectionDistributor类,这个类是用于派发注册事件到相应的 SelectorRunner上,它的派发方式是这样:
public Future<RegisterChannelResult> registerChannelAsync(
SelectableChannel channel, int interestOps, Object attachment,
CompletionHandler completionHandler)
throws IOException {
SelectorRunner runner = getSelectorRunner (interestOps);
return transport.getSelectorHandler ().registerChannelAsync(
runner, channel, interestOps, attachment, completionHandler);
}
private SelectorRunner getSelectorRunner(int interestOps) {
SelectorRunner[] runners = getTransportSelectorRunners();
int index;
if (interestOps == SelectionKey.OP_ACCEPT || runners.length == 1) {
index = 0;
} else {
index = (counter.incrementAndGet() % (runners.length - 1)) + 1;
}
return runners[index];
}
getS |