<Executorname="tomcatThreadPool"namePrefix="catalina-exec-" maxThreads="7"minSpareThreads="4"maxQueueSize="3"/> <!-- A "Connector" using the shared thread pool--> <Connectorexecutor="tomcatThreadPool" port="8080"protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
java.util.concurrent.RejectedExecutionException: The executor's work queue is full at org.apache.catalina.core.StandardThreadExecutor.execute(StandardThreadExecutor.java:179) at org.apache.tomcat.util.net.AbstractEndpoint.processSocket(AbstractEndpoint.java:1105) at org.apache.tomcat.util.net.NioEndpoint$Poller.processKey(NioEndpoint.java:896) at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:872) at java.lang.Thread.run(Thread.java:750)
Executes the given command at some time in the future. The command may execute in a new thread, in a pooled thread, or in the calling thread, at the discretion of the Executor implementation. If no threads are available, it will be added to the work queue. If the work queue is full, the system will wait for the specified time and it throw a RejectedExecutionException if the queue is stillfull after that.
// org.apache.tomcat.util.threads.ThreadPoolExecutor#execute(java.lang.Runnable, long, java.util.concurrent.TimeUnit) // @deprecated This will be removed in Tomcat 10.1.x onwards @Deprecated publicvoidexecute(Runnable command, long timeout, TimeUnit unit){ submittedCount.incrementAndGet(); try { executeInternal(command); } catch (RejectedExecutionException rx) { if (getQueue() instanceof TaskQueue) { // If the Executor is close to maximum pool size, concurrent // calls to execute() may result (due to Tomcat's use of // TaskQueue) in some tasks being rejected rather than queued. // If this happens, add them to the queue. final TaskQueue queue = (TaskQueue) getQueue(); try { // 如果是TaskQueue,这里还会等一会儿,如果还是失败,再抛出异常 if (!queue.force(command, timeout, unit)) { submittedCount.decrementAndGet(); thrownew RejectedExecutionException(sm.getString("threadPoolExecutor.queueFull")); } } catch (InterruptedException x) { submittedCount.decrementAndGet(); thrownew RejectedExecutionException(x); } } else { submittedCount.decrementAndGet(); throw rx; } } }
// org.apache.catalina.core.StandardThreadExecutor#execute(java.lang.Runnable) @Override publicvoidexecute(Runnable command){ if (executor != null) { // Note any RejectedExecutionException due to the use of TaskQueue // will be handled by the o.a.t.u.threads.ThreadPoolExecutor // 没地方传超时 executor.execute(command); } else { thrownew IllegalStateException(sm.getString("standardThreadExecutor.notStarted")); } }
// org.apache.tomcat.util.net.AbstractEndpoint#processSocket publicbooleanprocessSocket(SocketWrapperBase<S> socketWrapper, SocketEvent event, boolean dispatch){ try { // 省略 SocketProcessorBase<S> sc = processorCache.pop(); Executor executor = getExecutor(); if (dispatch && executor != null) { executor.execute(sc); } else { sc.run(); } } catch (RejectedExecutionException ree) { getLog().warn(sm.getString("endpoint.executor.fail", socketWrapper) , ree); returnfalse; } catch (Throwable t) { ExceptionUtils.handleThrowable(t); // This means we got an OOM or similar creating a thread, or that // the pool and its queue are full getLog().error(sm.getString("endpoint.process.fail"), t); returnfalse; } returntrue; }
// org.apache.tomcat.util.net.NioEndpoint.Poller#processKey if (!processSocket(attachment, SocketEvent.OPEN_READ, true)) { closeSocket = true; } if (closeSocket) { cancelledKey(sk); }
// org.apache.tomcat.util.net.NioEndpoint.Poller#cancelledKey // If attachment is non-null then there may be a current // connection with an associated processor. 1. getHandler().release(ka); 2. key.cancel(); 3. ka.getSocket().close(true); 4. countDownConnection();