Hazelcast ScheduledExecutor任务队列已满

Hazelcast ScheduledExecutor任务队列已满,hazelcast,Hazelcast,我正在向HazelcastisScheduledExecutorService(Hazelcast 3.12.4)提交任务 这一直运作良好,现在突然我得到错误 java.util.concurrent.RejectedExecutionException: Maximum capacity (200) of tasks reached, for scheduled executor (delayedEventExecutor). Reminder that tasks must be dispo

我正在向Hazelcast
isScheduledExecutorService
(Hazelcast 3.12.4)提交任务

这一直运作良好,现在突然我得到错误

java.util.concurrent.RejectedExecutionException: Maximum capacity (200) of tasks reached, for scheduled executor (delayedEventExecutor). Reminder that tasks must be disposed if not needed.
        at com.hazelcast.scheduledexecutor.impl.ScheduledExecutorContainer.checkNotAtCapacity(ScheduledExecutorContainer.java:337)
        at com.hazelcast.scheduledexecutor.impl.ScheduledExecutorContainer.schedule(ScheduledExecutorContainer.java:92)
        at 

com.hazelcast.scheduledexecutor.impl.operations.ScheduleTaskOperation.run(ScheduleTaskOperation.java:45)
其他问题,如,似乎表明我们需要调用
future.dispose()
,处理返回的future。但是任务是在将来执行的(这是一个要点)——我们是否需要保留某种列表中的所有未来,并在它们执行后
dispose()
它们?这似乎很疯狂。我想我们可以给任务一个对
未来
的引用,然后在
run()
方法调用
dispose()
的末尾,但这似乎很愚蠢(更不用说executor服务是分布式的,任务可能需要序列化并移动到另一个节点)


我们如何调用
dispose()
对未来执行数小时的
Future
s任务?或者是否有其他方法来停止此错误消息?

isScheduledExecutorService
创建并执行在给定延迟后启用的一次性操作。 它有两个与您的问题相关的配置属性:

  • 池大小
    :执行器的每个成员的执行器线程数
  • 容量
    :计划程序每个分区可以执行的最大任务数。 任务应由用户通过调用
    future.dispose()
    来释放容量
您可以在此处找到文档:

IScheduledFuture
对象保留在列表中并在以后处理它们只会占用容量。相反,您可以调用
future.get()
来获取结果,并在执行后立即进行处理,如果需要,将结果保存在列表中

举例说明:

ArrayList resultList = new ArrayList<Integer>();
IScheduledExecutorService executorService = member.getScheduledExecutorService("myScheduler");
IScheduledFuture<Integer> future = executorService.schedule(
                new SampleTask(), 10, TimeUnit.SECONDS);

int result= future.get(); // Block until we get the result
resultList.add(result);
future.dispose(); // Always dispose futures that are not in use any more, to release resources
ArrayList resultList=new ArrayList();
isScheduledExecutorService executorService=member.getScheduledExecutorService(“myScheduler”);
isScheduledFuture=executorService.schedule(
新的SampleTask(),10,时间单位为秒);
int result=future.get();//封锁直到我们得到结果
结果列表。添加(结果);
future.dispose();//始终处置不再使用的期货,以释放资源
与计划任务相关联的未来始终被强烈引用,以便了解丢失的分区和/或成员,充当本地成员/客户端上的侦听器。 根据特定于分区的调度,未来的任务既存储在主分区中,也存储在其N个备份中。如果Hazelcast成员丢失,将在备份上重新安排任务。 在特定于成员的调度中,未来任务只存储在成员本身中,这意味着在成员丢失的情况下,任务也会丢失


如果您不想用<代码>将来.GET()/代码>,直到得到结果,请考虑查看<代码> I/O(代码>

< p>)这种代码对我来说无效:

IScheduledExecutorService executorService = member.getScheduledExecutorService("myScheduler");
IScheduledFuture<Integer> future = executorService.schedule(
                new SampleTask(), 3, TimeUnit.HOURS);

int result = future.get(); // Block the calling thread for 3 hours and crash the server
future.dispose(); 
isScheduledExecutorService executorService=member.getScheduledExecutorService(“myScheduler”);
isScheduledFuture=executorService.schedule(
新的SampleTask(),3,TimeUnit.HOURS);
int result=future.get();//阻止调用线程3小时并使服务器崩溃
future.dispose();

所以我的解决方案是建立一个基于数据库的延迟执行器。我将Springbean名称、方法名称和序列化参数以及传递时间戳存储在数据库中。最糟糕的是,我必须定期轮询数据库以查找需要交付的事件。如果时间到了,我将使用
applicationContext.getBean()
调用来查找实例,反序列化参数并使用反射调用
方法。成功后,我将删除数据库数据。

在得到结果之前,我不想阻塞-如果我想要,我不需要ScheduledExecutor,我只需要同步运行任务。另外,如果我计划任务在3小时内执行,我会阻止线程3小时吗?我的服务器会崩溃。此外,这些任务是可序列化的,实际上可能在不同的节点上执行。
IScheduledExecutorService executorService = member.getScheduledExecutorService("myScheduler");
IScheduledFuture<Integer> future = executorService.schedule(
                new SampleTask(), 3, TimeUnit.HOURS);

int result = future.get(); // Block the calling thread for 3 hours and crash the server
future.dispose();