SchedleDexecutorservice.ScheduleAtfixedrate ووضع initialdelay حتى الآن في الماضي

StackOverflow https://stackoverflow.com/questions/3196888

  •  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
);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top