例程myProcessToRun()需要执行100次,但每次执行之间大约需要一秒钟的延迟。
以下FOR循环与ScheduledThreadPoolExecutor对象一起使用。
for (int n=0; n<100; n++)
{
final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
executor.schedule(new Runnable() {
@Override
public void run() {
myProcessToRun();
}
}, (n+2), TimeUnit.SECONDS);
}
这实际上工作正常,但线程仍然保留。使用JVisualVM,在执行例程时,线程数将增加100个线程。例程完成后,仍保留100个线程。
单击“ Perform GC”按钮不会清除它们,因此Java仍然认为它们应该存在。
使用上面的示例如何清理这些线程?
-编辑-
我注意到ScheduledThreadPoolExecutor在Loop中被实例化,这是一个糟糕的主意。将其移出LOOP之后,创建的线程还不错。
尝试实施解决方案后,出现了意外的行为。
final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
for (int n=0; n<100; n++)
{
//final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2);
executor.schedule(new Runnable() {
@Override
public void run() {
doAddNewCondSet();
}
}, (n+2), TimeUnit.SECONDS);
}
try
{
executor.shutdown();
if (!executor.awaitTermination(400, TimeUnit.SECONDS))
executor.shutdownNow();
} catch (InterruptedException e1)
{
e1.printStackTrace();
}
使用修改后的代码,它将立即关闭所有进程,并且不执行任何操作。与executor.shutdown(); 注释掉并仅使用awaitTermination(),程序刚刚挂起,几分钟后,所有进程同时启动,而没有延迟,从而导致错误。
我怀疑我的实现是错误的。
您可以通过多种方法来执行此操作。您可以在此处查看其中的一些内容:https : //www.baeldung.com/java-executor-wait-for-threads
我个人最喜欢的是CountDownLatch:
接下来,让我们看一下解决此问题的另一种方法-使用CountDownLatch表示任务已完成。
我们可以使用一个值来初始化它,该值表示在通知所有调用await()方法的线程之前,它可以递减的次数。
例如,如果我们需要当前线程等待另外N个线程完成执行,则可以使用N初始化闩锁:
ExecutorService WORKER_THREAD_POOL
= Executors.newFixedThreadPool(10);
CountDownLatch latch = new CountDownLatch(2);
for (int i = 0; i < 2; i++) {
WORKER_THREAD_POOL.submit(() -> {
try {
// ...
latch.countDown();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
// wait for the latch to be decremented by the two remaining threads
latch.await();
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句