AbstractIoAcceptor類繼承自AbstractIoService基類,並實現了IoAcceptor接口,它主要的成員變量是本地綁定地址。
private final List<SocketAddress> defaultLocalAddresses =
new ArrayList<SocketAddress>();
private final List<SocketAddress> unmodifiableDefaultLocalAddresses =
Collections.unmodifiableList(defaultLocalAddresses);
private final Set<SocketAddress> boundAddresses =
new HashSet<SocketAddress>();
在調用bind或unbind方法時需要先獲取綁定鎖bindLock,具體的綁定操作還是在bind0這個方法中實現的。一旦綁定成功後,就會向服務監聽者發出服務激活的事件(ServiceActivated),同理,解除綁定也是在unbind0這個方法中具體實現的。一旦解除綁定成功後,就會向服務監聽者發出服務激活的事件(ServiceDeActivated)。
AbstractIoConnector類繼承自AbstractIoService基類,並實現了IoConnect接口,連接超時檢查間隔時間默認是50毫秒,超時時間默認爲1分鐘,用戶可以自行配置。此類中重要的方法就是connect方法,其中調用了具體的連接邏輯實現connect0,
protected abstract ConnectFuture connect0(SocketAddress remoteAddress,
SocketAddress localAddress, IoSessionInitializer<? extends ConnectFuture> sessionInitializer);
AbstractIoConnector在AbstractIoService的基礎上,在會話初始化結束時增加了一個功能,就是加入了一個監聽者,當連接請求被取消時立即結束此會話。
protected final void finishSessionInitialization0(
final IoSession session, IoFuture future) {
// In case that ConnectFuture.cancel() is invoked before
// setSession() is invoked, add a listener that closes the
// connection immediately on cancellation.
future.addListener(new IoFutureListener<ConnectFuture>() {
public void operationComplete(ConnectFuture future) {
if (future.isCanceled()) {
session.close();
}
}
});
}
下面再來看一個IoProcessor接口的基本實現類SimpleIoProcessorPool,它的泛型參數是AbstractIoSession的子類,表示此Processor管理的具體會話類型。並且這個類還實現了池化,它會將多個IoSession分佈到多個IoProcessor上去管理。下面是文檔中給出的一個示例:
// Create a shared pool.
SimpleIoProcessorPool<NioSession> pool =
new SimpleIoProcessorPool<NioSession>(NioProcessor.class, 16);
// Create two services that share the same pool.
SocketAcceptor acceptor = new NioSocketAcceptor(pool);
SocketConnector connector = new NioSocketConnector(pool);
// Release related resources.
connector.dispose();
acceptor.dispose();
pool.dispose();
與Processor池有關的包括如下這些成員變量:
private static final int DEFAULT_SIZE = Runtime.getRuntime().availableProcessors() + 1;//處理池大小,默認是處理器數+1, 便於多核分佈處理
private final IoProcessor<T>[] pool;//IoProcessor池
private final AtomicInteger processorDistributor = new AtomicInteger();
Processor池的構造過程,其中有三種構造函數供選擇來構造一個Processor :
1.帶參數 ExecutorService 的構造函數.
2.帶參數爲 Executor的構造函數.
3.默認構造函數
pool = new IoProcessor[size];//構建池
boolean success = false;
try {
for (int i = 0; i < pool.length; i ++) {
IoProcessor<T> processor = null;
//有三種構造函數供選擇來構造一個Processor
try {
try {
processor = processorType.getConstructor(ExecutorService.class).newInstance(executor);
} catch (NoSuchMethodException e) {
// To the next step
}
if (processor == null) {
try {
processor = processorType.getConstructor(Executor.class).newInstance(executor);
} catch (NoSuchMethodException e) {
// To the next step
}
}
if (processor == null) {
try {
processor = processorType.getConstructor().newInstance();
} catch (NoSuchMethodException e) {
// To the next step
}
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeIoException(
"Failed to create a new instance of " + processorType.getName(), e);
}
pool[i] = processor;
}
success = true;
} finally {
if (!success) {
dispose();
}
}
從Processor池中分配一個processor的過程,注意一個processor是可以同時管理多個session的。
private IoProcessor<T> getProcessor(T session)
{//返回session所在的processor,若沒分配,則爲之分配一個
IoProcessor<T> p = (IoProcessor<T>) session.getAttribute(PROCESSOR);//看session的屬性中是否保存對應的Processor
if (p == null)
{//還沒爲此session分配processor
p = nextProcessor();//從池中取一個processor
IoProcessor<T> oldp =
(IoProcessor<T>) session.setAttributeIfAbsent(PROCESSOR, p);
if (oldp != null)
{//原來的processor
p = oldp;
}
}
return p;
}
private IoProcessor<T> nextProcessor()
{//從池中分配一個Processor
checkDisposal();
return pool[Math.abs(processorDistributor.getAndIncrement()) % pool.length];
}