我正在尝试创建一个将在特定时间执行的线程,持续一段特定的时间并且只运行一次,然后停止直到再次调用它。
问题在于,无论何时执行线程,它都不会在一段时间内执行,它只会打印一个" Hi"然后立即停止。 如果我删除该标志,该线程将永远运行。
public void startExecutionAt(int targetHour, int targetMin, int duration)
{
log.info("Create thread!");
Runnable taskWrapper= new Runnable(){
@Override
public void run()
{
if(runsFirst==true){
log.info("Thread inside!");
WateringScheduler.execute();
startExecutionAt(targetHour, targetMin, duration);
}
else{
log.info("Thread stoped!");
stop();
//close the led
}
runsFirst=false;
}
};
long delay = computeNextDelay(targetHour, targetMin);
System.out.println("Delay is : " + delay + " Duration is: " +duration);
executorService.scheduleAtFixedRate(taskWrapper, delay,duration, TimeUnit.SECONDS);
}
private static long computeNextDelay(int targetHour, int targetMin) {
LocalDateTime localNow = LocalDateTime.now();
ZoneId currentZone = ZoneId.systemDefault();
ZonedDateTime zonedNow = ZonedDateTime.of(localNow, currentZone);
ZonedDateTime zonedNextTarget = zonedNow.withHour(targetHour).withMinute(targetMin);
if (zonedNow.compareTo(zonedNextTarget) > 0) {
zonedNextTarget = zonedNextTarget.plusDays(1);
}
Duration duration = Duration.between(zonedNow, zonedNextTarget);
return duration.getSeconds();
}
public void stop()
{
executorService.shutdown();
try {
executorService.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException ex) {
log.error("Error");;
}
}
public static void execute(){
System.out.println("Hi");
//open the led;
}
答案 0 :(得分:1)
我使用ScheduledExecutorService感到困惑。
根据javadocs,“ScheduledFuture计划创建并执行一次性动作,在给定的延迟后启用。”
下面的代码执行一次线程并在(延迟+持续时间)+1后停止。
public void startExecutionAt(int targetHour, int targetMin, int duration)
{
log.info("Create thread!");
long delay = computeNextDelay(targetHour, targetMin);
final Runnable executeR = new Runnable() {
public void run() {
try {
execute();
}catch(Exception ex) {
log.error("Error in thread" + ex.getMessage());
}
}
};
final ScheduledFuture<?> executeHandler = executorService.scheduleAtFixedRate(executeR,delay, duration, TimeUnit.SECONDS);
executorService.schedule(
new Runnable() {
public void run() {
log.info("Thread is stopping");
executeHandler.cancel(true);
}
}, delay+duration+1, TimeUnit.SECONDS);
System.out.println("Delay is : " + delay + " Duration is: " +duration);
log.info("Thread out");
}
private static long computeNextDelay(int targetHour, int targetMin) {
LocalDateTime localNow = LocalDateTime.now();
ZoneId currentZone = ZoneId.systemDefault();
ZonedDateTime zonedNow = ZonedDateTime.of(localNow, currentZone);
ZonedDateTime zonedNextTarget = zonedNow.withHour(targetHour).withMinute(targetMin);
if (zonedNow.compareTo(zonedNextTarget) > 0) {
zonedNextTarget = zonedNextTarget.plusDays(1);
}
Duration duration = Duration.between(zonedNow, zonedNextTarget);
return duration.getSeconds();
}
public void stop()
{
executorService.shutdown();
try {
executorService.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException ex) {
log.error("Error");;
}
}