Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

不断向ExecutorService提交可运行的任务,直到工作完成,获取java.util.concurrent.RejectedExecutionException

问题描述: 不断向ExecutorService提交可运行的任务,直到工作完成,获取java.util.concurrent.RejectedExecutionException。

回答: 在Java中,ExecutorService是一个用于管理线程池的接口,它提供了一种方便的方式来执行并发任务。当我们向ExecutorService提交任务时,它会将任务分配给线程池中的线程来执行。然而,在某些情况下,当线程池已经饱和或者无法接受更多任务时,ExecutorService可能会抛出java.util.concurrent.RejectedExecutionException异常。

java.util.concurrent.RejectedExecutionException是一个运行时异常,表示ExecutorService无法接受或执行提交的任务。这通常发生在以下情况下:

  1. 线程池已经达到了最大线程数限制,并且所有线程都正在执行任务。
  2. ExecutorService已经被关闭,不再接受新的任务。

为了解决这个问题,我们可以采取以下几种方法:

  1. 捕获异常并处理:在向ExecutorService提交任务时,可以使用try-catch语句来捕获RejectedExecutionException异常,并根据需要进行处理。例如,可以选择重新提交任务、记录日志或者通知用户等。
  2. 使用有界队列:可以在创建ExecutorService时,使用有界队列来限制任务的提交速度。当队列已满时,ExecutorService将拒绝接受新的任务,并抛出RejectedExecutionException异常。这样可以避免线程池过载,但可能会导致一些任务被丢弃。
  3. 调整线程池参数:可以通过调整线程池的参数来增加线程池的容量,以便能够接受更多的任务。可以调整的参数包括核心线程数、最大线程数、线程空闲时间等。
  4. 使用其他ExecutorService实现:除了Java标准库提供的ExecutorService实现,还可以考虑使用其他第三方库或框架提供的ExecutorService实现。这些实现可能具有更灵活的配置选项,以及更好的性能和扩展性。

总结: 当不断向ExecutorService提交可运行的任务,直到工作完成时,如果出现java.util.concurrent.RejectedExecutionException异常,说明ExecutorService无法接受或执行提交的任务。为了解决这个问题,可以捕获异常并处理、使用有界队列、调整线程池参数或者使用其他ExecutorService实现。具体的解决方法应根据实际情况和需求来选择。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

面试-线程池的成长之路

线程池是一种多线程处理形式,处理过程中将任务提交到线程池,任务的执行交由线程池来管理。...这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。...每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。...说说线程池的拒绝策略 当请求任务不断的过来,而系统此时又处理不过来的时候,我们需要采取的策略是拒绝服务。RejectedExecutionHandler接口提供了拒绝任务处理的自定义方法的机会。...,将任务插入到队列中,直到队列中有空闲并插入成功的时候,否则将根据最大等待时间一直阻塞,直到超时。

63120

ThreadPool介绍

默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当向线程池提交一个任务时,若线程池已创建的线程数小于corePoolSize,即便此时存在空闲线程,也会通过创建一个新线程来执行该任务...线程池流程 image.png 当提交一个新任务到线程池时,线程池的处理流程如下: 首先线程池判断基本线程池是否已满?没满,创建一个工作线程来执行任务。满了,则进入下个流程。...其次线程池判断工作队列是否已满?没满,则将新提交的任务存储在工作队列里。满了,则进入下个流程。 最后线程池判断整个线程池是否已满?...没满,则创建一个新的工作线程来执行任务,满了,则交给饱和策略来处理这个任务。...Executors.newFixedThreadPool(int n):创建一个可重用固定个数的线程池,以共享的无界队列方式来运行这些线程。一批n个线程执行完之后,再次返回线程池继续下一波任务。

72231
  • 面试-线程池的成长之路

    从易到难,都是这么个过程,还有就是确实很多人在工作中接触线程池比较少,最多的也就是创建一个然后往里面提交线程,对于一些经验很丰富的面试官来说,一下就可以问出很多线程池相关的问题,与其被问的晕头转向,还不如好好学习...这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。...每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。...也就是即将被执行的任务,并尝试再次提交当前任务。...,将任务插入到队列中,直到队列中有空闲并插入成功的时候,否则将根据最大等待时间一直阻塞,直到超时。

    60220

    ExecutorService 并发指南

    这适用于工作负载可预测的场景。固定池大小确保了一致的并发级别,但如果工作负载超过了可用线程,任务可能会排队等待可用的工人。...拒绝策略 当我们向一个已满的线程池的 ExecutorService 提交任务时,如果线程池无法接受新的任务,这些任务会被提交到线程池的阻塞队列中。...extends Callable> tasks): 这个方法允许提交一系列 Callable 任务,并返回包含结果的 List。它阻塞调用线程直到所有任务完成。...处理任务结果: 通过遍历 Future 列表,调用 future.get() 获取每个任务的结果。此操作阻塞当前线程直到任务完成,但由于任务是并发执行的,整个过程依然很高效。...线程饥饿: 在使用缓存线程池时,频繁的短暂任务可能导致线程池不断创建和销毁线程。这种行为会消耗大量资源,并可能使长期运行的任务无法获得足够的 CPU 时间。

    15310

    【Java】已解决java.util.concurrent.RejectedExecutionException异常

    是Java并发编程中常见的一个异常,它通常发生在使用ExecutorService(如ThreadPoolExecutor)执行异步任务时,当任务提交到线程池但线程池无法处理新任务(比如,因为已经关闭了或者达到了其最大容量...二、可能出错的原因 线程池已满且RejectedExecutionHandler的默认策略是抛出异常。 线程池已关闭,无法接受新任务。 提交的任务数量超过了线程池的最大处理能力。...); // 提交任务(注意这里应有一个合理的控制,防止无限制地提交任务) // ... // 当不再需要提交新任务时...当线程池不能接受新任务时,它会尝试在调用execute的线程中运行该任务。 五、注意事项 在设计线程池时,要充分考虑系统的并发需求和资源限制,合理设置线程池的大小和队列容量。...对于需要长时间运行的任务,建议使用单独的线程或线程池来处理,避免阻塞核心线程池。 在使用线程池时,要注意优雅地关闭线程池,避免资源泄露。

    79010

    阿里规范竟然不让我用这种方式创建线程池

    如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。...实际上我们也可以理解为FixedThreadPool该线程池中的线程数量始不变。当有一个新的任务提交时,线程池中若有空闲线程,则立即执行。...若多余一个任务被提交到该线程 池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务 public static ExecutorService newSingleThreadExecutor...若所有线程均在工作,又有新 的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复 用。...这时候如果提交的线程数超过了可用线程数的时候,就会抛出异常,比如 java.util.concurrent.RejectedExecutionException,这是因为当前线程池使用的队列是有边界队列

    39240

    再见了Future,图解JDK21虚拟线程的结构化并发

    // 阻塞直到提交的任务完成 String output = future.get(); // 打印 "Done" System.out.println(output); // 继续执行后续任务.../ get()将阻塞直到任务1完成 TaskResult result1 = future1.get(); // get()将阻塞直到任务2完成 TaskResult result2...3 上述实现的问题 如在上面代码中用Platform线程,则存在一个问题。获取TaskResult的get()方法将阻塞线程,由于与阻塞Platform线程相关的可扩展性问题,这代价可能很昂贵。...4 结构化并发 想象,从方法内部向ExecutorService提交的任务,然后方法退出。现在更难推断代码,因为不知道此提交的任务可能的副作用,且这可能导致难以调试的问题。...ExecutorService的try-with-resources块是对结构化并发的一次良好尝试,其中从块内提交的所有任务在块退出时完成。但它还不够,因为它可能导致父线程等待时间超过必要时间。

    2K10

    一步一步分析RejectedExecutionException异常

    ,运行之后抛异常 } } 运行一下,看到如下输出: pool-1-thread-1 执行任务 0 pool-1-thread-3 执行任务 2 pool-1-thread-2 执行任务 1 Exception...当线程池里的线程都繁忙的时候,新任务会被提交给阻塞队列保存,这个阻塞队列一旦饱和,线程池就会拒绝接收新任务,随即抛出异常。...,运行之后抛异常 } } 在上面的例子中,我们使用了一个大小为15的ArrayBlockingQueue阻塞队列来保存等待执行的任务。...接着我们提交了20个任务给线程池,由于每个线程执行任务的时候会睡眠0.5秒,因此当3个线程繁忙的时候,其他任务不会立即得到执行,我们提交的新任务会被保存在队列里。...其实我们可以给使用ArrayBlockingQueue作为阻塞队列的ThreadPoolExecutor线程池提交超过15个的任务,只要我们在提交新任务前设置一个完成原来任务的等待时间,这时3个线程就会逐渐消费

    5.7K30

    线程池核心源码深度剖析:原理、实战与优化

    通过 execute() 方法向线程池提交 10 个任务,这些任务会被分配给线程池中的线程执行。每个任务打印当前线程名称并休眠 1 秒,模拟任务执行。...(三)STOP不接受新任务,也不处理队列中的任务,会中断正在执行的任务。(四)TIDYING所有任务都已终止,即将进行清理工作。(五)TERMINATED线程池终止完成。...(二)submit 方法submit(Callable task) 方法可提交 Callable 任务,并返回 Future 对象,可获取任务执行结果或取消任务。...十一、线程池提交任务到工作队列后的细节处理(一)任务队列类型ArrayBlockingQueue:有界阻塞队列,基于数组实现,需要指定容量。...工作线程不断从任务队列中获取任务执行,任务执行完后继续获取下一个任务,直到线程池关闭或队列为空。

    10221

    juc系列-Executor框架

    ,每提交一个任务时就创建一个线程,直到达到线程池的最大数量,此时线程池的规模不再变化(如果某个线程发生Exception而结束,那么线程池会补充一个新的线程) newCachedThreadPool:创建一个可缓存的线程池...有些任务可能已经完成,有些可能正在运行,而其他的任务可能在队列中等待执行。 为了解决执行任务的生命周期问题,ExecutorService扩展了Executor接口,添加了一些生命周期管理的方法。...SHUTDOWN:不接受新task,但是继续处理工作队列中的任务。 STOP:不接受新task,不处理工作队列中的任务,并且中断运行中的线程。...()后 关闭线程池方法 shutdown():不再接受新任务,同时已提交的任务执行完成,包括那些还在队列中等待,未开始执行的任务。...线程池工作流程 线程池处理新提交任务的流程如下: 如果当前运行的线程数小于配置的corePoolSize,就新建一个线程执行该command任务,即时此时线程池中有空闲线程。

    39111

    Java 多线程与线程池 Thread弊端与Executor存在问题 及解决方法

    newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。...线程池一共有五种状态, 分别是: RUNNING :能接受新提交的任务,并且也能处理阻塞队列中的任务; SHUTDOWN:关闭状态,不再接受新提交的任务,但却可以继续处理阻塞队列中已保存的任务。...然后看看 execute() 方法是如何处理的: ? 获取当前线程池的状态。 当前线程数量小于 coreSize 时创建一个新的线程运行。 如果当前线程处于运行状态,并且写入阻塞队列成功。...双重检查,再次获取线程状态;如果线程状态变了(非运行状态)就需要从阻塞队列移除任务,并尝试判断线程是否全部执行完毕。同时执行拒绝策略。 如果当前线程池为空就新创建一个线程并执行。...此时,LinkedBlockingQueue就是一个无边界队列,对于一个无边界队列来说,是可以不断的向队列中加入任务的,这种情况下就有可能因为任务过多而导致内存溢出问题。

    1.9K40

    Executor框架

    (Runnable command); } Executor 基于生产者-消费者模式,将任务的提交过程和执行过程解耦开来,提交任务的操作相当于生产者(生产待完成的工作单元);执行任务的线程相当于消费者(...工作者线程的任务很简单:从工作队列中获取一个任务,执行任务,然后返回线程池并等待下一个任务。 Java类库提供了一个灵活的线程池以及一些有用的配置。...ExecutorService 的生命周期有三种状态:运行、关闭和已终止。ExecutorService 在初始创建时处于运行状态。...Future表示一个任务的生命周期,并提供了相应的方法来判断是否已经完成或者取消,以及获取任务的结果和取消任务等。...CompletionService: Executor 与 BlockingQueue 完成任务(CompletionService):如果向Executor提交了一组计算任务,并希望在计算完成后获得结果

    55510

    【Java 线程池】Java 创建线程池的正确姿势: Executors 和 ThreadPoolExecutor 详解

    当在execute(Runnable)方法中提交新任务并且少于corePoolSize线程正在运行时,即使其他工作线程处于空闲状态,也会创建一个新线程来处理该请求。...它接收SchduledFutureTask类型的任务,有两种提交任务的方式: scheduledAtFixedRate scheduledWithFixedDelay SchduledFutureTask...,它会根据time的先后时间排序,若time相同则根据sequenceNumber排序; DelayQueue也是一个无界队列; 工作线程的执行过程: 工作线程会从DelayQueue取已经到期的任务去执行...此时,LinkedBlockingQueue就是一个无边界队列,对于一个无边界队列来说,是可以不断的向队列中加入任务的,这种情况下就有可能因为任务过多而导致内存溢出问题。..., new ArrayBlockingQueue(10)); 这种情况下,一旦提交的线程数超过当前可用线程数时,就会抛出java.util.concurrent.RejectedExecutionException

    36.6K56

    面试题系列:并发编程之线程池及队列

    线程池种类 newCachedThreadPool 用newCachedThreadPool()方法创建该线程池对象,创建之初里面一个线程都没有,当execute方法或submit方法向线程池提交任务时...当线程池达到corePoolSize时,新提交的任务将被放入workQueue中,等待线程池任务调度执行。...ThreadPoolExecutor.CallerRunsPolicy 用于被拒绝任务的处理程序,它直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务。...DelayQueue是一个支持延时获取元素的无界阻塞队列。队列使用PriorityQueue来实现。队列中的元素必须实现Delayed接口,在创建元素时可以指定多久才能从队列中获取当前元素。...定时任务调度:使用DelayQueue保存当天要执行的任务和执行时间,一旦从DelayQueue中获取到任务就开始执行,比如Timer就是使用DelayQueue实现的。

    99820

    笔记09 - 线程池刨根问底

    我们知道CPU运行的最小单位是线程,Java中实现并发是通过多线程来完成的,利用多线程提高了对CPU资源的利用率,但是线程的创建和销毁是很消耗性能的。...线程的创建、调度都是由子类实现的; ExecutorService:继承自Executor,在Executor内部实现了任务提交机制以及线程池关闭的方法; ThreadPoolExecutor:ExecutorService...上面的代码中一次性提交了5个异步任务,每个异步任务内部耗时操作500ms,此时线程池就会不断创建新的线程来执行异步任务: ? 下面修改一下代码,每次向线程池中提交异步任务的时候等待1000ms: ?...上面的代码中向newFixedThreadPool中一次性提交了10个任务,但是任务只会被3个线程分配执行。 ?...当前线程池中运行的线程数量已经达到了corePoolSize数量,线程池会将新加入的任务放到等待队列中,直到某一个线程空闲了,线程池会根据等待队列中设置的优先级规则,取出一个任务执行; 3.

    34210

    21.3 Java 线程池

    ():包含固定数量线程并共享无界队列的线程池;当所有线程处于工作状态,有新任务提交时,任务在队列中等待,直到一个线程变为可用状态 newCachedThreadPool():只有需要时创建新线程的线程池...Runnable 或者 Callable 任务的执行结果进行取消、查询是否完成、获取结果。...必要时可以通过 get 方法获取执行结果,该方法会阻塞直到任务返回结果。...获取多个结果 如果向线程池提交了多个任务,要获取这些任务的执行结果,可以依次调用Future.get()获得。...向CompletionService批量提交任务后,只需调用相同次数的CompletionService.take()方法,就能获取所有任务的执行结果,获取顺序是任意的,取决于任务的完成顺序: void

    34420

    Executor框架

    图中2:在线程池完成预热之后(当前运行的线程数等于corePoolSize),将任务加入LinkedBlockingQueue。...上图2:在线程池完成预热之后(当前线程池中有一个运行的线程),将任务加入LinkedBlockingQueue。...这意味着,如果主线程提交任务的速度高于maximumPool中线程处理任务的速度时,CachedThreadPool会不断创建新线程。...获取Lock。 添加任务。 向PriorityQueue添加任务。 如果在上面2.1中添加的任务是PriorityQueue的头元素,唤醒在Condition中等待的所有线程。...)方法将以中断执行此任务线程的方式来试图停止任务;当FutureTask处于已启动状态时,执行FutureTask.cancel(false)方法将不会对正在执行此任务的线程产生影响(让正在执行的任务运行完成

    15310

    Java的Executor框架和线程池实现原理

    当线程完成任务时,会无限反复从链式阻塞队列中获取任务来执行 3,)newCachedThreadPool:可缓存线程池 public static ExecutorService newCachedThreadPool...每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数corePoolSize,则将提交的任务存入到池队列中。 2、newCachedThreadPool创建一个可缓存的线程池。...2).如果长时间没有往线程池中提交任务,即如果工作线程空闲了指定的时间(默认为1分钟),则该工作线程将自动终止。终止后,如果你又提交了新的任务,则线程池重新创建一个工作线程。...,才去创建新的线程(不能超过线程池的最大数maxmumPoolSize) 向线程池提交任务的两种方式: 1)通过execute()方法 ExecutorService threadpool= Executors.newFixedThreadPool...,它会返回一个Future对象,通过future的get方法来获取返回值,get方法会阻塞住直到任务完成,而使用get(long timeout, TimeUnit unit)方法则会阻塞一段时间后立即返回

    44520

    线程池学习总结

    这样就实现了Thread对象的重复利用,也就减少了创建线程和销毁线程所消耗的资源。当需要向线程池提交任务时会调用阻塞队列的offer方法向队列的尾部添加任务。...每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。...2).如果长时间没有往线程池中提交任务,即如果工作线程空闲了指定的时间(默认为1分钟),则该工作线程将自动终止。终止后,如果你又提交了新的任务,则线程池重新创建一个工作线程。...单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的 。...二.CachedThreadPool的特点就是在线程池空闲时,即线程池中没有可运行任务时,它会释放工作线程,从而释放工作线程所占用的资源。

    44020

    Java线程池详解

    线程池添加线程的规则 当此时新来一个任务需要执行,线程池会怎么处理? 1.如果线程数小于corePoolSize,即使其他工作线程处于空闲状态,也会创建一个新核心线程来运行新任务。...:如果 User Thread已经全部退出运行了,只剩下Daemon Thread存在了,虚拟机也就退出了,这是因为没有了“被守护者”,Daemon也就没有工作可做了,也就没有继续运行程序的必要了。...任务拒绝策略 任务拒绝时机 当Executor关闭时,提交新任务会被拒绝。 以及当Executor对最大线程和工作队列容量使用有限边界并且已经饱和时。...1.任务拒绝后让提交任务的线程去执行,比如主线程调用的execute方法,任务爆满拒绝后让主线程代劳执行,避免了业务损失。..., // 那么就去增加核心工作线程,直到线程数大于maximumPoolSize时,拒绝后面任务。

    39310
    领券