سؤال

البرنامج يحتوي على عنصر - يطلق عليها اسم "جدولة المهام" - أن يتيح المكونات الأخرى تسجيل نقاط في الوقت الذي يريدون ليتم استدعاؤها مرة أخرى.هذا يجب أن تعمل كثيرا مثل Unix كرون،.هـ.تقول جدولة "يخطر لي عشر دقائق بعد كل ساعة كاملة".

وأنا أدرك أن هناك أي رد في جاوة.

هنا هو بلدي النهج ، هل هناك مكتبة الذي يفعل هذه الأشياء ؟ لا تتردد في اقتراح التحسينات أيضا.

تسجيل مكالمة جدولة يمر:

  • الوقت تحتوي على مواصفات ساعة, دقيقة, ثاني, السنة الشهر, دوم, داو, حيث كل بند من بنود قد تكون غير محددة ، وهذا يعني "تنفيذ كل ساعة / دقيقة.... الخ" (تماما مثل crontabs)
  • كائن التي تحتوي على البيانات التي سوف اقول استدعاء كائن ماذا تفعل عندما يتم إعلامك عن طريق جدولة.جدولة لا معالجة هذه البيانات فقط مخازن و يمر عليه مرة أخرى بناء على إخطار.
  • في إشارة إلى استدعاء كائن

عند بدء التشغيل او بعد تسجيل جديد طلب جدولة يبدأ التقويم كائن من وقت النظام الحالي و يتحقق إذا كان هناك أي الإدخالات في قاعدة البيانات التي تطابق هذه النقطة في الوقت المناسب.إذا كان هناك يتم تنفيذها و تبدأ العملية أكثر.إذا لم تكن هناك الوقت في التقويم الكائن بمقدار ثانية واحدة entreis يتم إعادة الفحص.هذا يكرر حتى يكون هناك إدخال واحد أو أكثر من مباراة(es).(منفصلة الحدث المحاكاة)

جدولة ثم تذكر أن الزمني, النوم والاستيقاظ كل ثانية للتحقق مما إذا كان هو بالفعل هناك.إذا كان يحدث أن يستيقظ الوقت قد مرت بالفعل ، ويبدأ أكثر ، وبالمثل إذا كان الوقت قد حان و الوظائف التي تم تنفيذها.


تحرير:شكرا على توضيحك لي الكوارتز.أنا أبحث عن شيء أصغر من ذلك بكثير, ومع ذلك.

هل كانت مفيدة؟

المحلول

إذا كان لديك احتياجات بسيطة, النظر في استخدام java.util.توقيت:

public class TimerDemo {

  public static void main(String[] args) {
    // non-daemon threads prevent termination of VM
    final boolean isDaemon = false;
    Timer timer = new Timer(isDaemon);

    final long threeSeconds = 3 * 1000;
    final long delay = 0;
    timer.schedule(new HelloTask(), delay, threeSeconds);

    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.MINUTE, 1);
    Date oneMinuteFromNow = calendar.getTime();

    timer.schedule(new KillTask(timer), oneMinuteFromNow);
  }

  static class HelloTask extends TimerTask {
    @Override
    public void run() {
      System.out.println("Hello");
    }
  }

  static class KillTask extends TimerTask {

    private final Timer timer;

    public KillTask(Timer timer) {
      this.timer = timer;
    }

    @Override
    public void run() {
      System.out.println("Cancelling timer");
      timer.cancel();
    }
  }

}

كما تم وأشار, ، ExecutorService من java.util.المتزامنة تقدم أكثر ثراء API إذا كنت في حاجة إليها.

نصائح أخرى

البحث الكوارتز

إذا كانت الأشياء تعرف بالضبط النقاط الفردية في الوقت الذي كانوا يرغبون في تنفيذها, ثم هل يمكن استخدام java.util.concurrent.ScheduledExecutorService.ثم أنها دعوة بسيطة:

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
long timeToExecute = ... //read from DB? use CronTrigger?
long delayToExecution = timeToExecute - System.currentTimeMillis();
scheduler.schedule(aRunnable, delayToExecution, TimeUnit.MILLISECONDS);

أنت تحتاج فقط إلى استخدام Quartz إذا كنت تريد جدولة نفسها للتعامل مع وظائف مثل "تنفيذ كل 5 ثواني", أو إذا كنت ترغب في مجمع السلوك في جميع أنحاء غاب الإعدام ، أو استمرار تنفيذ المراجعة.

يمكنك فعلا مسلي إعادة استخدام الكوارتز CronTrigger فئة للحصول على "التالي وقت التنفيذ".الفئة هو مستقل تماما و لا تعتمد على الاستشهاد به من داخل Quartz "السياق".مرة واحدة كنت قد القادم وقت التنفيذ كما Date أو long, يمكنك فقط استخدام جافا ScheduledExecutorService على النحو الوارد أعلاه

الكوارتز هو كبير و واضح قوة في هذا المجال ، ولكن هناك بعض البدائل لاستكشاف.

Cron4j هو لائق بما فيه الكفاية المكتبة ، وهذا هو قليلا أكثر خفيفة الوزن من الكوارتز.فإنه يوفر وثائق جيدة و سوف تفعل ما تريد.

ربما أكثر إثارة للاهتمام إذا كنت ترغب في استخدام المكتبة الذي يناسب بشكل أفضل مع جافا التزامن المكتبات (وخاصة منفذي و ScheduledExecutors) ثم ها JDBC لديه CronExecutorService واجهة بتنفيذها CronThreadPoolExecutor.الآن, ومن المثير للاهتمام, وقد الاعتماد على الكوارتز (لتوفير CronExpression فئة), ولكن أجد أن اثنين معا العمل أفضل من مجرد الكوارتز وحده.إذا كنت لا تريد كبير تبعيات من السهل استخراج قليل من الطبقات من الكوارتز و ها JDBC أن جعل هذا يحدث.

منذ كنت تريد شيئا أصغر بكثير (فقط لاحظت تحرير) ، والاستيلاء CronExpression من الكوارتز ، ها-JDBC الطبقات التي ذكرتها أعلاه.أن عليك أن تفعل ذلك.

أود أن أوصى بشدة cron4j (سبق ذكره) أكثر من الكوارتز ، إلا إذا كنت في حاجة على الإطلاق بعض أكثر تطورا وتعقيدا الميزات من الكوارتز.Cron4j يركز بشكل جيد على ما يفترض القيام به ، لائق الوثائق ، وليس مطبخ بالوعة الحل.

الكوارتز جدولة ينصح عادة.

لا أصدق جافا.util.توقيت كان صوت الجواب.الكوارتز هو حقا خيار أفضل بكثير.

ميزة كبيرة من الكوارتز على جافا.util.الموقت هو أنه مع الكوارتز الوظائف التي يمكن تخزينها في قاعدة البيانات.نتيجة واحدة jvm يمكن جدولة آخر يمكن تنفيذ.أيضا (من الواضح) طلب قيد الحياة عبر jvm إعادة تشغيل.

ربما أكثر إثارة للاهتمام إذا كنت ترغب في استخدام المكتبة الذي يناسب بشكل أفضل مع جافا التزامن المكتبات (وخاصة منفذي و ScheduledExecutors) ثم ها JDBC لديه CronExecutorService واجهة بتنفيذها CronThreadPoolExecutor.الآن, ومن المثير للاهتمام, وقد الاعتماد على الكوارتز (لتوفير CronExpression فئة), ولكن أجد أن اثنين معا العمل أفضل من مجرد الكوارتز وحده.إذا كنت لا تريد كبير تبعيات من السهل استخراج قليل من الطبقات من الكوارتز و ها JDBC أن جعل هذا يحدث.

أردت فقط أن أقول إنني حاولت استخراج هذه الطبقات ، وانها عملت!أنا في حاجة هذه الفئات الثلاث:

  • CronExpression (الكوارتز)
  • CronThreadPoolExecutor (ha-jdbc)
  • DaemonThreadFactory (ha-jdbc)

وأنا فقط ان تعديلات طفيفة:

  • إزالة مسجل من CronThreadPoolExecutor (تم إنشاؤه ولكنها لم تستخدم)
  • انتقلت المستمر YEAR_TO_GIVEUP_SCHEDULING_AT من CronTrigger إلى CronExpression

كنت سعيدة أنني لم تتعثر سحب في مجموعة متشابكة من التبعيات.مبروك إلى فئة الكتاب!

وأنه كان يعمل مثل بطل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top