What are the possible reason for a java.util.concurrent.RejectedExecutionException in a SingleThreadExecutor
JavaMultithreadingJava Problem Overview
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));
}
Java Solutions
Solution 1 - Java
There are two reasons why execute
would throw a RejectedExecutionException
- The queue is full and you cannot add any more threads
- The ThreadPool has been shutdown
Since you are using a LinkedBlockingQueue
the only way I can see this occurring is because you shutdown the pool.
Solution 2 - Java
You might have submitted tasks after calling executor.shutdown()
. Normally to stop executor they do
executor.shutdown();
executor.awaitTermination(10, TimeUnit.MINUTES);
Solution 3 - Java
Maybe you should use a thread pool instead of using a single executor.
executor = new java.util.concurrent.ThreadPoolExecutor(30, 30, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new ThreadFactory() {
final AtomicInteger threadNumber = new AtomicInteger( 1 );
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "Thread No : " + threadNumber.getAndIncrement());
}
});
Solution 4 - Java
Threads are not available to execute the given task. No linked block queue to que task.