切换 ScheduledExecutorService 所以它并不总是 运行
Toggle ScheduledExecutorService so its not always running
我目前正在开发一个 discord 机器人,只是为了搞乱,但过去曾使用 SES 做其他事情,但我总是难以 disable/enable SES,调用 ses.shutdown();
不工作,runnable 继续,如果我关闭了我不知道如何重新启动它。
这是我当前的代码...
private final ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
protected void startRainbow(Role rle) {
roleRainbow[] colors = roleRainbow.values();
HashMap<String, Integer> map = new HashMap<>();
map.put("loop", 0);
Runnable r = () -> {
if(map.get("loop") >= colors.length) {
map.put("loop", 0);
}
rle.getManager().setColor(Color.decode(colors[map.get("loop")].toString())).queue();
System.out.println("color is: " + colors[map.get("loop")].toString());
System.out.println("color from role: " + rle.getColor());
map.put("loop", map.get("loop") + 1);
};
ses.scheduleAtFixedRate(r, 1L, 1, TimeUnit.SECONDS);
}
这个问题有两个角度:
- 正在中断 currently-running 线程。
- 正常关闭计划的执行程序服务。
第一个问题已经解决 many many times on Stack Overflow。简而言之:您必须向线程发出信号,表明您希望它中断自身。该线程的任务必须编码就是这样一种寻找中断信号的方式。
对于第二种,涉及两个步骤:
- 您首先告诉计划的执行程序服务您要停止任何进一步执行 future-scheduled 任务。我们通过调用
shutdown
来完成此操作。此调用 不会 中断任何当前存在的任务(见上段)。
- 或者,您可以调用
shutdownNow
。此调用 可能 向 运行 任务发出中断信号,但不能保证。行为是 implementation-defined.
- 请求服务停止进一步调度后,您可以观察服务是否确实在经过一段合理的时间后停止。我们通过调用
awaitTermination
. 来做到这一点
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor() ;
ses.scheduleAtFixedRate( task , initialDelay , period , timeUnit ) ;
…
ses.shutdown() ;
boolean terminated = false ;
try { terminated = ses.awaitTermination( 1 , TimeUnit.MINUTES ); } catch ( InterruptedException e ) { e.printStackTrace(); }
if( ! terminated ) { … Houston, we have a problem. … }
对shutdown
(和shutdownNow
)的调用不会阻塞;它不等待任何事情发生,也不等待任务结束。
对 awaitTermination
的调用确实 阻塞,直到:
- 计划的执行程序服务完成其最后一个 运行 任务,然后结束。
- 指定的 time-out 已过。
测试 awaitTermination
调用返回的布尔值。引用 Javadoc:
true
if this executor terminated and false
if the timeout elapsed before termination
你问过:
if I did shutdown im not sure how to restart it.
一旦关闭,预定的执行程序服务就完成了。要安排任务执行,您必须实例化一个新的计划执行程序服务。
请注意,没有要执行的任务的计划执行程序服务占用非常少的内存或CPU。因此,如果您以后可能需要该服务,则无需关机。
但是,请务必始终 在您的应用程序结束之前关闭您的执行程序服务。否则后备线程池可能会 运行 无限期地继续,就像僵尸 ♂️。
我目前正在开发一个 discord 机器人,只是为了搞乱,但过去曾使用 SES 做其他事情,但我总是难以 disable/enable SES,调用 ses.shutdown();
不工作,runnable 继续,如果我关闭了我不知道如何重新启动它。
这是我当前的代码...
private final ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
protected void startRainbow(Role rle) {
roleRainbow[] colors = roleRainbow.values();
HashMap<String, Integer> map = new HashMap<>();
map.put("loop", 0);
Runnable r = () -> {
if(map.get("loop") >= colors.length) {
map.put("loop", 0);
}
rle.getManager().setColor(Color.decode(colors[map.get("loop")].toString())).queue();
System.out.println("color is: " + colors[map.get("loop")].toString());
System.out.println("color from role: " + rle.getColor());
map.put("loop", map.get("loop") + 1);
};
ses.scheduleAtFixedRate(r, 1L, 1, TimeUnit.SECONDS);
}
这个问题有两个角度:
- 正在中断 currently-running 线程。
- 正常关闭计划的执行程序服务。
第一个问题已经解决 many many times on Stack Overflow。简而言之:您必须向线程发出信号,表明您希望它中断自身。该线程的任务必须编码就是这样一种寻找中断信号的方式。
对于第二种,涉及两个步骤:
- 您首先告诉计划的执行程序服务您要停止任何进一步执行 future-scheduled 任务。我们通过调用
shutdown
来完成此操作。此调用 不会 中断任何当前存在的任务(见上段)。- 或者,您可以调用
shutdownNow
。此调用 可能 向 运行 任务发出中断信号,但不能保证。行为是 implementation-defined.
- 或者,您可以调用
- 请求服务停止进一步调度后,您可以观察服务是否确实在经过一段合理的时间后停止。我们通过调用
awaitTermination
. 来做到这一点
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor() ;
ses.scheduleAtFixedRate( task , initialDelay , period , timeUnit ) ;
…
ses.shutdown() ;
boolean terminated = false ;
try { terminated = ses.awaitTermination( 1 , TimeUnit.MINUTES ); } catch ( InterruptedException e ) { e.printStackTrace(); }
if( ! terminated ) { … Houston, we have a problem. … }
对shutdown
(和shutdownNow
)的调用不会阻塞;它不等待任何事情发生,也不等待任务结束。
对 awaitTermination
的调用确实 阻塞,直到:
- 计划的执行程序服务完成其最后一个 运行 任务,然后结束。
- 指定的 time-out 已过。
测试 awaitTermination
调用返回的布尔值。引用 Javadoc:
true
if this executor terminated andfalse
if the timeout elapsed before termination
你问过:
if I did shutdown im not sure how to restart it.
一旦关闭,预定的执行程序服务就完成了。要安排任务执行,您必须实例化一个新的计划执行程序服务。
请注意,没有要执行的任务的计划执行程序服务占用非常少的内存或CPU。因此,如果您以后可能需要该服务,则无需关机。
但是,请务必始终 在您的应用程序结束之前关闭您的执行程序服务。否则后备线程池可能会 运行 无限期地继续,就像僵尸 ♂️。