SchedleDexecutorservice.ScheduleAtfixedrate ووضع initialdelay حتى الآن في الماضي
-
02-10-2019 - |
سؤال
أنا أعمل على نظام جدولة في جافا يرسل تذكيرات بناءً على أ تاريخ البدء, تاريخ الانتهاء و حادثة (كل ساعة ، يوميًا ، أسبوعيًا ، شهريًا ، يوم الاثنين ، إلخ). في الأصل كنت أستخدم مؤقت و Timertask فصول لتحديد موعد للتذكير:
Timer timer = new Timer();
timer.scheduleAtFixedRate(reminder, firstDate, period);
لقد تحولت مؤخرًا إلى ScheduleDexecutorService لذلك يمكن أن يكون لدي المزيد من التحكم في إلغاء الأحداث. ال ScheduleDexecutorService يعمل بشكل جيد للتذكير المتكرر ، باستثناء حالة واحدة لإعادة جدولة التذكير مع أ تاريخ البدء في الماضي. ال ScheduleAtfixedrate تتيح لك الوظيفة فقط تحديد طويل قيمة ل تأخير مبدأي, وليس فعليًا تاريخ هدف:
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(reminder, initialDelay, period, unit);
هذا يمثل مشكلة ، لأن المرور سلبيا تأخير مبدأي لا يزال يتسبب في إطلاق الحدث على الفور ، مما يؤدي إلى إعادة تشغيله في حاليا + فترة, ، عوضا عن تاريخ البدء + فترة.
أي أفكار كيف يمكنني (إعادة) جدولة تذكير مع تاريخ البدء في الماضي؟
المحلول
ما عليك سوى القيام بفحص سريع لمعرفة ما إذا كان التاريخ في الماضي ، ثم قم بإنشاء DateTime بدءًا مؤقتًا جديدًا وهو زيادة في الماضي الآن.
نصائح أخرى
قمت بحلها عن طريق تشغيلها مرة واحدة على بدء التشغيل ، ثم في ذلك الوقت أردت كل يوم:
// check once initial on startup
doSomething();
// and then once every day at midnight utc
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
LocalDateTime firstRun = LocalDate.now(ZoneOffset.UTC).atStartOfDay().plusDays(1);
Duration durationUntilStart = Duration.between(LocalDateTime.now(ZoneOffset.UTC), firstRun);
scheduler.scheduleAtFixedRate(
() -> doSomething(),
durationUntilStart.getSeconds() + 1,
Duration.ofDays(1).getSeconds(),
TimeUnit.SECONDS
);