I create the following executor in a singleton:
final private ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactory() { final ThreadFactory delegate = Executors.defaultThreadFactory(); public Thread newThread(Runnable paramAnonymousRunnable) { Thread localThread = this.delegate.newThread(paramAnonymousRunnable); localThread.setName("MyTask-" + localThread.getName()); localThread.setDaemon(XXX.this.daemonThread); return localThread; } });
And during the execution of the program, there a lot call to this method of the singleton. The calls are done in different threads and maybe at the sametime.
private void send(final String paramString) { try { this.executor.execute(new Runnable() { public void run() { //DO some interesting stuff } }); } catch (Exception localException) { this.handler.handle(localException); }
}
And at some point the following stacks start to appear:
java.util.concurrent.RejectedExecutionException at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1774) at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:768) at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:656) at java.util.concurrent.Executors$DelegatedExecutorService.execute(Executors.java:589) at XXXXX.send(XXXX.java:269)
Why the jvm will throw such exception?
The singleThreadExecutor is backed by a LinkedBlockingQueue().
And the thread pool wasn't shutdown.
for information, the jvm is oracle jdk 1.6. The singleton is created with spring. copy from java.util.concurrent.Executors:
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory)); }
RejectedExecutionException: rejected from java. util. concurrent. ThreadPoolExecutor error occurs when the thread pool queue is full and no further threads can be created in spring boot.
The RejectedExecutionException exception is thrown when a task can't be accepted by the executor for execution. Generally there are two scenarios when a task is rejected for execution: The executor service has already been shut down.
The concurrent API in Java provides a feature known as an executor that initiates and controls the execution of threads. As such, an executor offers an alternative to managing threads using the thread class. At the core of an executor is the Executor interface.
If you have constrained your thread pool to only allow a certain number of concurrent threads (generally a good thing), then the application needs to somehow push-back on the calling code, so when you receive a RejectedExecutionException from the ThreadPoolExecutor you need to indicate this to the caller and the caller ...
There are two reasons why execute
would throw a RejectedExecutionException
Since you are using a LinkedBlockingQueue
the only way I can see this occurring is because you shutdown the pool.
You might have submitted tasks after calling executor.shutdown()
. Normally to stop executor they do
executor.shutdown(); executor.awaitTermination(10, TimeUnit.MINUTES);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With