您创建了池大小为 4 的 ScheduledThreadPoolExecutor,因此它一次最多只能运行 4 个任务,即使有更多项目超过了预期的启动延迟。其余的将不得不等待执行程序线程之一可用。您可以使用以下简单代码进行演示,该代码记录活动线程数并计算每个线程的任务数:
// import java.util.concurrent.atomic.AtomicInteger;
int delay = 5000;
ScheduledThreadPoolExecutor threadPoolExecutorScheduler = new ScheduledThreadPoolExecutor(4);
var threads = new ConcurrentHashMap<String,AtomicInteger>();
for (int i = 0; i < 10; i++) {
threadPoolExecutorScheduler.schedule(() -> {
String tName = Thread.currentThread().getName();
threads.computeIfAbsent(tName, tn -> new AtomicInteger()).incrementAndGet();
System.out.println(tName+" Start threads#"+threads.size() + " = "+threads);
try {Thread.sleep(20000); } catch(Exception lost) {}
System.out.println(tName+" END");
}
, delay, TimeUnit.MILLISECONDS);
}
提交10个任务,延迟5秒,可以看到最大线程数为4,后6个任务只有前4个完成才能启动。
pool-1-thread-2 Start threads#1 = {pool-1-thread-3=1, pool-1-thread-2=1, pool-1-thread-4=1}
pool-1-thread-4 Start threads#3 = {pool-1-thread-3=1, pool-1-thread-2=1, pool-1-thread-4=1}
pool-1-thread-3 Start threads#2 = {pool-1-thread-3=1, pool-1-thread-2=1, pool-1-thread-4=1}
pool-1-thread-1 Start threads#4 = {pool-1-thread-1=1, pool-1-thread-3=1, pool-1-thread-2=1, pool-1-thread-4=1}
pool-1-thread-2 END
pool-1-thread-2 Start threads#4 = {pool-1-thread-1=1, pool-1-thread-3=1, pool-1-thread-2=2, pool-1-thread-4=1}
pool-1-thread-3 END
pool-1-thread-3 Start threads#4 = {pool-1-thread-1=1, pool-1-thread-3=2, pool-1-thread-2=2, pool-1-thread-4=1}
pool-1-thread-4 END
pool-1-thread-4 Start threads#4 = {pool-1-thread-1=1, pool-1-thread-3=2, pool-1-thread-2=2, pool-1-thread-4=2}
pool-1-thread-1 END
pool-1-thread-1 Start threads#4 = {pool-1-thread-1=2, pool-1-thread-3=2, pool-1-thread-2=2, pool-1-thread-4=2}
pool-1-thread-2 END
pool-1-thread-2 Start threads#4 = {pool-1-thread-1=2, pool-1-thread-3=2, pool-1-thread-2=3, pool-1-thread-4=2}
pool-1-thread-3 END
pool-1-thread-3 Start threads#4 = {pool-1-thread-1=2, pool-1-thread-3=3, pool-1-thread-2=3, pool-1-thread-4=2}
pool-1-thread-4 END
pool-1-thread-1 END
pool-1-thread-2 END
pool-1-thread-3 END
您已经达到了同时运行太多任务的地步——这要么是任务中的缺陷,要么您可能需要考虑不同的线程/执行器服务策略。根据@Basil Bourque 的回答项目,LOOM 可以让处理变得更容易。
使用像 Eclipse 这样不错的 IDE 进一步诊断/调试,添加日志语句(可能不是 log4j!),并使用堆栈跟踪(jstack <pid> 或控制台中的 CTRL-Break)等其他信息来帮助您识别代码失败了。