1.1.1.1 startInternal方法
这个方法是核心的启动方法,目前理解主要做了两件事情,第一件是创建轮询线程,即具体的读取线程,它是进行具体的处理,第二个是创建创建监听请求线程,它是等待请求,然后交给轮训进行处理。
public void startInternal() throws Exception {
if (!running) {
running = true;
paused = false;
//一种带锁的栈,processorCache
processorCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getProcessorCache());
//事件缓存
eventCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getEventCache());
//nio管道
nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getBufferPool());
// Create workercollection
if (getExecutor() == null ) {
createExecutor(); //实例化当前对象的成员变量executor,构建了一个线程池
}
initializeConnectionLatch();
//Poller的数量控制如果不设置的话最大就是2
pollers = new Poller[getPollerThreadCount()];
for (int i=0; i<pollers.length; i++) {
pollers[i] = new Poller();
Thread pollerThread = new Thread(pollers[i], getName() + "-ClientPoller-"+i);
pollerThread.setPriority(threadPriority);//用来设置进程、进程组和用户的进程执行优先权
pollerThread.setDaemon(true);//设置为守护线程
pollerThread.start();
}
startAcceptorThreads();
}
}
1.1.1.1.1 Poller启动
它是被设计成了守护线程,并且进行启动,其run方法如下,采用选择器的非阻塞方式,如果没有获取到注册事件返回空,下面迭代为空所以就什么都没有执行,如果返回不为空则会执行processKey方法。
public void run() {
//这是一个线程,所以进行死循环
while (true) {
try {
//如果是暂停并且未关闭则睡10s
while (paused &&(!close) ) {
try {
Thread.sleep(100);
} catch (InterruptedExceptione) {
}
}
boolean hasEvents = false;
//如果关闭之后,执行完毕时间后,关闭选择器
if (close) {
events();
timeout(0, false);
try {
selector.close();
} catch (IOExceptionioe) {
log.error(sm.getString(
"endpoint.nio.selectorCloseFail"), ioe);
}
break;
} else {
hasEvents = events();
}
/**
* 如果endpoint是正常工作状态,处理已有的数据。
* 通过events方法来处理当前Poller中已有的事件(数据)。
* 同时使用selector.select或者selectNow来获取这个Poller上
* */
try {
if ( !close ) {
if (wakeupCounter.getAndSet(-1) > 0) {
//if we are here, means we have other stuff to do
//do a nonblocking select