gpt4 book ai didi

java - 从主程序退出的应用程序未停止运行

转载 作者:行者123 更新时间:2023-12-01 16:16:06 24 4
gpt4 key购买 nike

我正在编写一个Java代码,根据给定的时区在每个午夜打印一些行。
例如,如果我在IST时区上运行我的应用程序,并且想根据午夜CET时区打印数据,那么我会将时间转换为CET。为此,我使用ScheduledExecutorService方法scheduleAtFixedRate(),其中我根据时区计算延迟。
下面是代码

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class MainClass {

private ScheduledExecutorService executor = null;
private static final long TOLERANCE_DELAY_TO_MIDNIGHT = 120000L;
private static final int SCHEDULE_HOUR = 0;
private static final int SCHEDULE_MINUTE = 0;
final int ONE_DAY_MILLIS = 24 * 60 * 60 * 1000;

public MainClass() {
executor = Executors.newScheduledThreadPool(1);
final Schedule schedule = new Schedule();
this.executor.scheduleAtFixedRate(schedule, schedule.getScheduleDelay(), ONE_DAY_MILLIS, TimeUnit.MILLISECONDS);
}

private void printTime(final long delay) {
final long millis = delay % 1000;
final long second = (delay / 1000) % 60;
final long minute = (delay / (1000 * 60)) % 60;
final long hour = (delay / (1000 * 60 * 60)) % 24;

final String time = String.format("%02d:%02d:%02d.%d", hour, minute, second, millis);
System.out.println(time);
}

private long convertDateTimeZone(final long lngDate, final String fromTimeZone, final String toTimeZone) {
final TimeZone toTZ = TimeZone.getTimeZone(toTimeZone);
final Calendar toCal = Calendar.getInstance(toTZ);

final TimeZone fromTZ = TimeZone.getTimeZone(fromTimeZone);
final Calendar fromCal = Calendar.getInstance(fromTZ);
fromCal.setTimeInMillis(lngDate);
toCal.setTimeInMillis(fromCal.getTimeInMillis() + toTZ.getOffset(fromCal.getTimeInMillis())
- TimeZone.getDefault().getOffset(fromCal.getTimeInMillis()));
return toCal.getTimeInMillis();
}

private final class Schedule implements Runnable {

private Schedule() {
System.out.println("Scheduler started");
}

public void waitForMidnight() {
long shift = getShiftToMidnight();
System.out.println("shift to midnight = " + shift + "ms");
while (shift > 0) {
try {
Thread.sleep(shift);
} catch (final InterruptedException e) {
// ignore
}
shift = getShiftToMidnight();
}
}

//return the shift to midnight with tolerance value 2 minutes
private long getShiftToMidnight() {
final Calendar tomorrow = new GregorianCalendar();
tomorrow.add(Calendar.DATE, 1);
final Calendar tomorrow0000 = new GregorianCalendar(tomorrow.get(Calendar.YEAR),
tomorrow.get(Calendar.MONTH), tomorrow.get(Calendar.DATE), SCHEDULE_HOUR, SCHEDULE_MINUTE);
final long nowTime = convertDateTimeZone(System.currentTimeMillis(), "IST", "CET");
final long delay = tomorrow0000.getTimeInMillis() - nowTime;
if (delay > TOLERANCE_DELAY_TO_MIDNIGHT) {
return 0L;
}
return delay;
}

private final long getScheduleDelay() {
System.out.println("running");
final Calendar today = new GregorianCalendar();
final Calendar todayMidnight = new GregorianCalendar(today.get(Calendar.YEAR), today.get(Calendar.MONTH),
today.get(Calendar.DATE), 24, 0, 0);
final long currentTime = convertDateTimeZone(System.currentTimeMillis(), "IST", "CET");
long delay = todayMidnight.getTimeInMillis() - currentTime;
printTime(delay);
delay = (delay < 0) ? 0 : delay;
return delay;
}

@Override
public void run() {
System.out.println("hit");
waitForMidnight();
System.out.println("midnight);
}

}

public static void main(final String[] args) {
final MainClass scheculer = new MainClass();
System.out.println("exit from main");
}

}


问题在于,应用程序在等待run方法调用之前退出main()。延迟是正确计算的,我没有得到它为什么会这样发生。

最佳答案

您正在丢失executor.scheduleAtFixedRate的结果,该结果返回Future。您应该从主目录调用future.get停止退出,但是请注意,直到您确定何时取消其他地方的计划任务,此get()调用才会返回以允许正常退出。

关于java - 从主程序退出的应用程序未停止运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62387563/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com