Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:SingleThreadScheduledExecutor&;java.util.concurrent.RejectedExecutionException_Java_Multithreading_Exception_Concurrency_Executor - Fatal编程技术网

Java:SingleThreadScheduledExecutor&;java.util.concurrent.RejectedExecutionException

Java:SingleThreadScheduledExecutor&;java.util.concurrent.RejectedExecutionException,java,multithreading,exception,concurrency,executor,Java,Multithreading,Exception,Concurrency,Executor,我有这个问题,我有 private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); 以及每50 millliseconds创建一次的任务: executor.scheduleAtFixedRate(myTask, 0, 50, TimeUnit.MILLISECONDS); myTask有时需要一段时间才能完成(比如2-3秒左右),但newSingleThrea

我有这个问题,我有

private ScheduledExecutorService executor =  
     Executors.newSingleThreadScheduledExecutor(); 
以及每50 millliseconds创建一次的任务:

executor.scheduleAtFixedRate(myTask, 0, 50, TimeUnit.MILLISECONDS);
myTask
有时需要一段时间才能完成(比如2-3秒左右),但newSingleThreadScheduledExecutor保证下一个计划的myTask将等待当前任务完成

但是,我时常会遇到这样的错误:

执行:
java.util.concurrent.RejectedExecutionException


我该怎么办?谢谢

以下情况之一时将引发此异常:

  • 你已经关闭了执行者
  • 已超出执行器的工作队列或最大线程的界限
  • 我认为后者正在发生。当您执行任务并花费很长时间时,由于池中没有足够的可用线程,后续计划任务将无法运行

    要么:

  • 使用更大的池大小或使用cachedThreadPool
  • 将拒绝策略更改为例如使用ThreadPoolExecutor.CallerRunPolicy
  • 为运行长期运行任务创建单独的执行器,并从计划任务中运行这些执行器。事实上,只要增加池大小,就可以使用相同的Executor实例执行此操作

  • 另请参见考虑执行人正在做什么。按照您的指示,它每50毫秒运行一个任务。假设此任务运行不到50毫秒,则一切正常。然而,每隔2-3秒运行一次。发生这种情况时,执行器仍会尝试每50毫秒执行一次,但因为它只有一个线程,所以无法执行,并拒绝在长时间运行的任务仍在进行时触发的执行。这会导致您看到的异常

    要解决此问题,您有两种选择(假设您希望使用单个线程):

  • 使用带有固定延迟的
    scheduleAtfixedDelay
    而不是
    scheduleAtFixedRate
    。如果仔细阅读javadoc,您将看到,
    scheduleWithFixedDelay
    将在一个任务完成和下一个任务开始之间等待50毫秒,因此它永远不会“重叠”,即使其中一个任务需要很长时间。相比之下,
    scheduleAtFixedRate
    将尝试每50毫秒执行一次,而不管每次执行需要多长时间

  • 更改执行器处理执行失败的方式。默认情况是记录一个异常,但您可以告诉它忽略它,例如。看看
    java.util.concurrent.RejectedExecutionHandler
    的子类,例如
    DiscardPolicy
    ,它只是默默地删除无法运行的任务。您可以通过直接构造
    ScheduledThreadPoolExecutor
    并将处理程序传递给构造函数来使用它们,而不是使用
    Executors
    工厂类


  • 我怀疑选项(1)正是您想要的。

    对于Java 7,它们都将等待第一次执行完成,然后开始下一次执行

    点击此处:

    或者在这里:

    请更具体地说明您所说的“不时”是什么意思。只有在调用ExecutorService上的
    execute()
    时才会引发该异常。实际上,executer可以抛出RejectedExecutionException。scheduleAtFixedRate()@Andrey,您需要给我们更多的信息,从显示异常的堆栈跟踪开始。@Jim,是的,我的意思是说“作业提交时”,而不是“不时”:)是的,有时当我调用scheduleAtFixedRate时会抛出RejectedExecutionException(不总是这样,但我想当我的任务需要比往常更多的时间来完成时,它会开始抛出异常).如何在我的情况下使用cachedThreadPool?executor.scheduleAtFixedRate(我的任务,0,50,时间单位.毫秒);如何更改ThreadPoolExecutor拒绝策略?谢谢you@skaffman:实际上,它与您在1中所说的正好相反。:)javadoc:scheduleAtFixedRate:如果此任务的任何执行时间超过其周期,则后续执行可能会延迟开始,但不会同时执行