64

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

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

并且在程序执行过程中,对单例的这个方法有很多调用。调用在不同的线程中完成,并且可能同时完成。

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

}

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

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)

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

singleThreadExecutor 由 LinkedBlockingQueue() 支持。
并且线程池没有关闭。

有关信息,jvm 是 oracle jdk 1.6。单例是用 spring 创建的。从 java.util.concurrent.Executors 复制:

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

4 回答 4

75

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

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

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

于 2013-09-25T13:32:51.463 回答
9

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

    executor.shutdown();
    executor.awaitTermination(10, TimeUnit.MINUTES);
于 2013-09-25T11:46:32.783 回答
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());
        }
    });
于 2013-09-25T11:38:48.853 回答
0

线程不可用于执行给定的任务。没有链接块队列到队列任务。

于 2018-09-10T07:52:54.097 回答