SingleThreadExecutor中java.util.concurrent.RejectedExecutionException的可能原因是什么

RJO*_*RJO 51 java multithreading

我在单例中创建以下执行程序:

   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;
        }
    });
Run Code Online (Sandbox Code Playgroud)

在程序执行期间,对单例的这种方法有很多调用.调用是在不同的线程中完成的,也许是在同一时间完成的.

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);
  }
Run Code Online (Sandbox Code Playgroud)

}

在某些时候,以下堆栈开始出现:

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)
Run Code Online (Sandbox Code Playgroud)

为什么jvm会抛出这样的异常?

singleThreadExecutor由LinkedBlockingQueue()支持.
线程池没有关闭.

有关信息,jvm是oracle jdk 1.6.单身是用弹簧创造的.从java.util.concurrent.Executors复制:

   public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
       return new FinalizableDelegatedExecutorService
           (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>(),
                                threadFactory));
   }
Run Code Online (Sandbox Code Playgroud)

Joh*_*int 60

execute抛出一个原因有两个原因RejectedExecutionException

  1. 队列已满,您无法再添加任何线程
  2. ThreadPool已经关闭

由于您使用LinkedBlockingQueue的唯一方法是我可以看到发生这种情况是因为您关闭了池.

  • @Choletski你不能.您将不得不创建一个新的`ExecutorService`. (2认同)

And*_*hev 9

您可能在调用 之后提交了任务executor.shutdown()。通常停止执行者他们做

    executor.shutdown();
    executor.awaitTermination(10, TimeUnit.MINUTES);
Run Code Online (Sandbox Code Playgroud)


cgo*_*gon 1

也许您应该使用线程池而不是使用单个执行器。

    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());
        }
    });
Run Code Online (Sandbox Code Playgroud)