سؤال

لدي رمز حيث أقوم بجدولة مهمة باستخدام java.util.timer.كنت أنظر حولي ورأيت ExecutorService يمكن أن تفعل الشيء نفسه.إذن هذا السؤال هنا، هل استخدمت Timer و ExecutorService لجدولة المهام، ما فائدة استخدام واحدة على الأخرى؟

أردت أيضًا التحقق مما إذا كان أي شخص قد استخدم Timer فئة وواجهت أي مشاكل التي ExecutorService حلت لهم.

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

المحلول

وفق جافا التزامن في الممارسة العملية:

  • Timer يمكن أن تكون حساسة للتغيرات في ساعة النظام، ScheduledThreadPoolExecutor ليس كذلك.
  • Timer يحتوي على مؤشر ترابط تنفيذ واحد فقط، لذا فإن المهمة التي تعمل لفترة طويلة يمكن أن تؤخر المهام الأخرى. ScheduledThreadPoolExecutor يمكن تهيئتها مع أي عدد من المواضيع.علاوة على ذلك، لديك السيطرة الكاملة على المواضيع التي تم إنشاؤها، إذا كنت تريد (من خلال توفير ThreadFactory).
  • تم طرح استثناءات وقت التشغيل TimerTask قتل هذا الموضوع واحد، وبالتالي صنع Timer ميت :-( ...أي.لن يتم تشغيل المهام المجدولة بعد الآن. ScheduledThreadExecutor لا يلتقط استثناءات وقت التشغيل فحسب، بل يتيح لك التعامل معها إذا أردت (عن طريق تجاوز afterExecute الطريقة من ThreadPoolExecutor).سيتم إلغاء المهمة التي طرحت استثناءً، ولكن سيستمر تشغيل المهام الأخرى.

إذا كنت تستطيع استخدام ScheduledThreadExecutor بدلاً من Timer, ، القيام بذلك.

شيء اخر...بينما ScheduledThreadExecutor غير متوفر في مكتبة Java 1.4، فهناك الجزء الخلفي من JSR 166 (java.util.concurrent) إلى جافا 1.2، 1.3، 1.4, ، والتي لديها ScheduledThreadExecutor فصل.

نصائح أخرى

إذا كان متاحًا لك، فمن الصعب التفكير في سبب لا لاستخدام إطار عمل Java 5.الاتصال:

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();

سوف أعطيك أ ScheduledExecutorService مع وظائف مماثلة ل Timer (أي.سيكون مترابطًا واحدًا) ولكن قد يكون الوصول إليه أكثر قابلية للتطوير قليلاً (تحت الغطاء، يستخدم بنيات متزامنة بدلاً من المزامنة الكاملة كما هو الحال مع Timer فصل).باستخدام أ ScheduledExecutorService يمنحك أيضًا مزايا مثل:

  • يمكنك تخصيصه إذا لزم الأمر (انظر newScheduledThreadPoolExecutor() أو ال ScheduledThreadPoolExecutor فصل)
  • يمكن أن تؤدي عمليات الإعدام "لمرة واحدة" إلى الحصول على نتائج

حول الأسباب الوحيدة للتمسك بها Timer يمكنني التفكير في:

  • وهو متاح قبل Java 5
  • يتم توفير فئة مماثلة في J2ME، مما قد يجعل نقل تطبيقك أسهل (ولكن لن يكون من الصعب جدًا إضافة طبقة تجريد مشتركة في هذه الحالة)

وExecutorService هو أحدث وأكثر عمومية. A الموقت هو مجرد موضوع الذي يمتد دوري الاشياء لديك المقرر لذلك.

ويمكن أن يكون ExecutorService بركة موضوع، أو حتى انتشرت عبر أنظمة أخرى في كتلة وتفعل أشياء مثل تنفيذ دفعة لمرة واحدة، وما إلى ذلك ...

وانظروا ما كل العروض للبت فيها.

إليك بعض الممارسات أكثر جيدة حول استخدام الموقت:

http://tech.puredanger.com/2008/09/22 / الموقت قواعد /

في عام، فما استقاموا لكم فاستقيموا استخدام الموقت للأشياء سريعة وقذرة والمنفذ لاستخدام أكثر قوة.

وسبب لي لتفضيل بعض الأحيان الموقت على Executors.newSingleThreadScheduledExecutor () هو أن أحصل على كود أنظف بكثير عندما كنت في حاجة جهاز ضبط الوقت لتنفيذها على المواضيع الخفي.

ومقارنة

private final ThreadFactory threadFactory = new ThreadFactory() {
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r);
        t.setDaemon(true);
        return t;
    }
};
private final ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(threadFactory); 

مع

private final Timer timer = new Timer(true);

وأفعل ذلك عندما كنت لا تحتاج إلى متانة من executorservice.

من صفحة وثائق أوراكل على جدولة ThreadPoolExecutor

أ ThreadPoolExecutor والتي يمكنها أيضًا جدولة الأوامر للتشغيل بعد تأخير معين، أو لتنفيذها بشكل دوري.هذه الفئة هي الأفضل الموقت عندما تكون هناك حاجة إلى مؤشرات ترابط عاملة متعددة، أو عندما تكون هناك حاجة إلى مرونة أو إمكانيات إضافية لـ ThreadPoolExecutor (التي تمتد هذه الفئة).

ExecutorService/ThreadPoolExecutor أو ScheduledThreadPoolExecutor يعد خيارًا واضحًا عندما يكون لديك عدة سلاسل عاملة.

إيجابيات ExecutorService زيادة Timer

  1. Timer لا يمكن الاستفادة من نوى وحدة المعالجة المركزية المتاحة على عكس ExecutorService خاصة مع المهام المتعددة باستخدام نكهات ExecutorService يحب ForkJoinPool
  2. ExecutorService يوفر واجهة برمجة التطبيقات التعاونية إذا كنت بحاجة إلى التنسيق بين مهام متعددة.افترض أنه يتعين عليك إرسال عدد N من مهام العامل وانتظر إكمالها جميعًا.يمكنك تحقيق ذلك بسهولة مع استدعاء الكل واجهة برمجة التطبيقات.إذا كنت ترغب في تحقيق نفس الشيء مع متعددة Timer المهام، فإنه لن يكون بسيطا.
  3. ThreadPoolExecutor يوفر واجهة برمجة تطبيقات أفضل لإدارة دورة حياة الموضوع.

    تعالج تجمعات مؤشرات الترابط مشكلتين مختلفتين:عادةً ما توفر أداءً محسنًا عند تنفيذ عدد كبير من المهام غير المتزامنة، نظرًا لانخفاض حمل الاستدعاء لكل مهمة، وتوفر وسيلة لتقييد الموارد وإدارتها، بما في ذلك سلاسل العمليات، المستهلكة عند تنفيذ مجموعة من المهام.يحتفظ كل ThreadPoolExecutor أيضًا ببعض الإحصائيات الأساسية، مثل عدد المهام المكتملة

    مزايا قليلة:

    أ.يمكنك إنشاء / إدارة / التحكم في دورة حياة الخيوط وتحسين النفقات العامة لتكلفة إنشاء سلسلة الرسائل

    ب.يمكنك التحكم في معالجة المهام (سرقة العمل، ForkJoinPool، invocall) وما إلى ذلك.

    ج.يمكنك مراقبة تقدم وصحة المواضيع

    د.يوفر آلية أفضل للتعامل مع الاستثناءات

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