Java 如何在ScheduledThreadPoolExecutor中调度数百个小的、长延迟的任务?

Java 如何在ScheduledThreadPoolExecutor中调度数百个小的、长延迟的任务?,java,multithreading,scheduled-tasks,executorservice,Java,Multithreading,Scheduled Tasks,Executorservice,在我的服务器中,我有许多(大约50-1000个)游戏正在运行,它们都希望每20秒执行一次简短的任务。为了使这项工作更有效率,我想我应该创建一个执行者,由所有人共享: ScheduledThreadPoolExecutor t = new ScheduledThreadPoolExecutor(4); t.setMaximumPoolSize(32); t.setKeepAliveTime(30, TimeUnit.SECONDS); 应该完成的任务很短;它只向另一个缓存

在我的服务器中,我有许多(大约50-1000个)游戏正在运行,它们都希望每20秒执行一次简短的任务。为了使这项工作更有效率,我想我应该创建一个执行者,由所有人共享:

    ScheduledThreadPoolExecutor t = new ScheduledThreadPoolExecutor(4);
    t.setMaximumPoolSize(32);
    t.setKeepAliveTime(30, TimeUnit.SECONDS);
应该完成的任务很短;它只向另一个缓存线程池提交一个
Runnable

    t.schedule(
            new Runnable() { @Override public void run() {
                log.info("End of turn for player " + player);
                // the process started here will indirectly schedule this task again
                ThreadPool.execute(...); 
            }},
            turnTime, TimeUnit.MILLISECONDS
    );
但是,大多数任务根本就没有执行过。这让我怀疑执行人已经满了,尽管任务很短

我假设在执行提交的任务之前的延迟中,执行者的线程不会用于该任务。这个假设正确吗?现在回想起来,
ScheduledThreadPoolExecutor
的文档并没有真正提到它更新:我对此进行了测试,假设是正确的


不管怎样,我怎样才能正确地处理这种情况呢?

为什么您有一个大的线程池(我假设您没有32个内核)将任务添加到另一个线程池中。当ExecutorService“已满”时,它会拒绝任务,通常会出现异常。我怀疑您没有记录Runnable中发生的任何异常。为什么游戏不在需要时直接向
线程池提交任务?为什么有必要安排时间@Peter可能是对的,这里没有捕捉到一些异常。@PeterLawrey核心池是4个大的(这是我有多少个核心),32个是最坏的情况。我将任务添加到另一个池中,因为这些任务可能需要一段时间,我只想使用计划执行器进行计时,而不是它的资源限制功能。@Gray他们不会直接提交任务,因为任务有延迟,我不想在任务开始时使用
线程。睡眠(20秒)
,因为这样会产生太多线程。当调用
t.schedule(…)
时,应该保存返回值,即
ScheduledFuture
。然后您应该在将来调用
get()
,这可能会引发异常。否则,提交的作业将抛出,您永远不会知道它。