RJO
RJO

Reputation: 1040

What are the possible reason for a java.util.concurrent.RejectedExecutionException in a SingleThreadExecutor

I created 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 are a lot calls to this method of the singleton. The calls are done in different threads and maybe at the same time.

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 stack trace occurred:

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 would the JVM throw such exception?

The singleThreadExecutor is backed by a LinkedBlockingQueue<Runnable>().
And the thread pool wasn't shut down.

The JVM is Oracle JDK 1.6. The singleton was created with Spring, copied 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));
   }

Upvotes: 80

Views: 120526

Answers (4)

John Vint
John Vint

Reputation: 40256

There are two reasons why execute would throw a RejectedExecutionException

  1. The queue is full and you cannot add any more threads
  2. The ThreadPool has been shut down

Since you are using a LinkedBlockingQueue, the only way I can see this occurring is because you shut down the pool.

Upvotes: 85

Vishnu Vardhana Reddy
Vishnu Vardhana Reddy

Reputation: 56

Threads are not available to execute the given task. No linked block queue to que task.

Upvotes: 0

Andrey Chaschev
Andrey Chaschev

Reputation: 16516

You might have submitted tasks after calling executor.shutdown(). Normally to stop executor they do

    executor.shutdown();
    executor.awaitTermination(10, TimeUnit.MINUTES);

Upvotes: 12

cgon
cgon

Reputation: 1981

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());
        }
    });

Upvotes: 1

Related Questions