我有一个带有计划任务的简单程序,可以触发一些计算。
在过程的最后,仍然有很多TIMED_WAITING和WAITING队列,这是我所没有想到的。
Compute Executor terminated: false
Individual Compute Executor terminated: false
== Thread "thread-compute-6": TIMED_WAITING (java.lang.ThreadGroup[name=compute,maxpri=5])
== Thread "thread-compute-4": TIMED_WAITING (java.lang.ThreadGroup[name=compute,maxpri=5])
== Thread "thread-compute-1": TIMED_WAITING (java.lang.ThreadGroup[name=compute,maxpri=5])
== Thread "thread-compute-2": TIMED_WAITING (java.lang.ThreadGroup[name=compute,maxpri=5])
== Thread "thread-compute-0": WAITING (java.lang.ThreadGroup[name=compute,maxpri=5])
== Thread "thread-compute-5": TIMED_WAITING (java.lang.ThreadGroup[name=compute,maxpri=5])
== Thread "thread-compute-3": TIMED_WAITING (java.lang.ThreadGroup[name=compute,maxpri=5])
我不知道为什么,这有什么风险以及如何防止(即良好的终止)。
public class SimpleMain {
static List<SimpleModule> modules;
static ExecutorService executorSingleCompute;
static ScheduledExecutorService executorCompute;
static ScheduledFuture<?> sfc = null;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
modules = new ArrayList<>();
modules.add(new SimpleModule("A", 1_000));
modules.add(new SimpleModule("B", 2_000));
modules.add(new SimpleModule("C", 350));
modules.add(new SimpleModule("D", 20));
modules.add(new SimpleModule("E", 600));
// - Compute Threads
// (daemon=false)
ThreadFactory threadFacoryCompute = new MyThreadFactory("compute",Thread.NORM_PRIORITY,false);
executorCompute = new ScheduledThreadPoolExecutor(1, threadFacoryCompute);
executorSingleCompute = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<>(), threadFacoryCompute);
// -- START --
sfc = executorCompute.scheduleAtFixedRate(new ComputeThread(), 0, 50, TimeUnit.MILLISECONDS);
// -- PLAYING --
try {
Thread.sleep(20_000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
// -- FINAL PAUSE --
sfc.cancel(false);
try {
boolean status = executorCompute.awaitTermination(1000, TimeUnit.MILLISECONDS);
System.out.printf("Compute Executor terminated: %b\n", status);
} catch (InterruptedException ex) {
System.out.printf("Compute Executor interrupted\n");
}
try {
boolean status = executorSingleCompute.awaitTermination(1000, TimeUnit.MILLISECONDS);
System.out.printf("Individual Compute Executor terminated: %b\n", status);
} catch (InterruptedException ex) {
System.out.printf("Individual Compute Executor interrupted\n");
}
// Debug
Thread.getAllStackTraces().keySet().stream()
.filter(t->("compute".equals(t.getThreadGroup().getName())))
.forEach(t -> System.out.printf("== Thread \"%s\": %s (%s)\n", t.getName(), t.getState().toString(), t.getThreadGroup()));
System.exit(0);
}
// Threads pour CoreAtvste
public static class ComputeThread implements Runnable {
@Override
public void run() {
long now = System.currentTimeMillis();
for (Module module : modules) {
Runnable runnable = () -> {
module.compute(now);
};
executorSingleCompute.submit(runnable);
}
}
}
/**
* Une threadFactory
*/
private static class MyThreadFactory implements ThreadFactory {
private final ThreadGroup group;
public MyThreadFactory(String name, int priority, boolean daemon) {
group = new ThreadGroup(name);
group.setMaxPriority(priority);
group.setDaemon(daemon);
}
long cnt = 0;
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r, "thread-" + group.getName() + "-" + cnt++);
return t;
}
}
}
和模块类:
public class SimpleModule {
private final Lock computeLock = new ReentrantLock();
private final String name;
private final long duration;
private long lastOuts = -1;
public SimpleModule(String name, long duration) {
this.name = name;
this.duration = duration;
}
public void compute(long when) {
if (computeLock.tryLock()) {
// Heavy operation
for (int i = 0; i < duration * 50; i++) {
Math.random();
}
computeLock.unlock();
}
}
}
答案 0 :(得分:2)
完成后,您致电awaitTermination
,但从未致电shutdown
或shutdownNow
,而只等了一秒钟。线程仍然在那里。要完全终止,请先致电shutdown
(或shutdownNow
)。然后,您可以在适当的时限内致电awaitTermination
,具体时限取决于您的工作需要多长时间。这样做,线程应该消失了!
编辑:您当然需要在两个执行器上都调用shutdown。