في الآونة الأخيرة ، واجهت متطلبات جديدة في المشروع ، وهو تنفيذ وظيفة يمكنها إضافة مهام محددة بشكل ديناميكي. عند الحديث عن هذا ، قد يقول بعض الناس أنه بسيط ، فقط استخدم الكوارتز ، إنه بسيط وخام. ومع ذلك ، فإن إطار عمل الكوارتز ثقيل للغاية ، والمشاريع الصغيرة ليست سهلة التشغيل. بالطبع ، قد يقول بعض الأشخاص أن JDK يوفر واجهة مؤقت ، وهو ما يكفي تمامًا. ومع ذلك ، فإن متطلبات مشروعنا عبارة عن نماذج متعددة الخيوط تمامًا ، في حين أن الموقت متاح واحد ، لذلك ، اختار المؤلف أخيرًا مجموعة خيوط JDK.
ما هو تجمع الخيوط
توفر Java أربعة أنواع من تجمعات الخيوط من خلال المنفذين ، وهي:
NewCachedThreadPool: قم بإنشاء تجمع خيوط قابلة للتخطيط. إذا تجاوز طول تجمع الخيوط احتياجات المعالجة ، فيمكنك إعادة تدوير مؤشرات الترابط الخاملة بمرونة. إذا لم يكن هناك إعادة تدوير ، قم بإنشاء موضوع جديد.
NewfixedThreadPool: يقوم بإنشاء تجمع مؤشر ترابط ثابت طوله يمكنه التحكم في الحد الأقصى لعدد مؤشرات الترابط ، وسوف تنتظر مؤشرات الترابط الزائدة في قائمة الانتظار.
NewsCheduledThreadPool: يقوم بإنشاء تجمع مؤشرات ترابط ثابت طوله يدعم تنفيذ المهمة المحددة والدورية.
NewsingLethReadExecutor: ينشئ تجمع مؤشرات ترابط واحد ، والذي سيستخدم فقط مؤشر ترابط عامل فريد لتنفيذ المهام ، مما يضمن تنفيذ جميع المهام بالترتيب المحدد (FIFO ، LIFO ، الأولوية).
يستخدم الملصق NewsCheduledThreadPool في المشروع. هذا كل شيء. بغض النظر عن عدد الملصقات التي تتواجد فيها ، فسوف تُظهر مهاراتك. جوجل ذلك وهو كثير.
الحصول على خدمة تجمع الخيوط
يستخدم المؤلف وضع Singleton للحصول على خدمة تجمع الخيوط. الرمز كما يلي:
/*** إنشاء تجمع الموضوع. * Author wuhf * date 2018/01/16 */الفئة العامة threadpoolutils {private static SecrledExecutorService ExecutorService ؛ ThreadPoolutils الخاص () {// إنشاء تجمع مؤشر ترابط يدويًا. ExecutorService = new SecrledThreadPoolexecutor (10 ، New BasicTreadFactory.Builder (). Namingpattern ("syncdata-schedule-pool- ٪ d"). Daemon (true) .build ()) ؛ } pluginconfigholder الفئة الثابتة الخاصة {private final static threadpoolutils مثيل = new threadpoolutils () ؛ } threadpoolutils الثابتة العامة getInstance () {return pluginconfigholder.instance ؛ } Public ScheduleDexecutorService getThReadPool () {return executorService ؛ }}مقاطعة تنفيذ رمز مؤشر ترابط التشغيل
لن أقول الكثير من الهراء ، الرمز كما يلي:
/*** تم مقاطعة مهمة في تجمع الخيوط. */interrupthread فئة عامة تنفذ Runnable {private int num ؛ InterruptTherThread (int num) {this.num = num ؛ } رميات الفراغ الثابتة العامة (سلسلة [] args) interruptedException {مؤشر ترابط interruptthread = مؤشر ترابط جديد (InterruptthRead (1)) ؛ ScheduleDfuture <؟> t = threadpoolutils.getInstance (). getThreadPool (). ScheduleAtfixedrate (Interruptthread ، 0،2 ، timeUnit.seconds) ؛ interruptthread interruptthread1 = interrupthread (2) ؛ threadpoolutils.getInstance (). getThreadPool (). ScheduleAtFixedRate (InterruptthRead1،0،2 ، timeunit.seconds) ؛ InterruptTreatRead interruptthread2 = InterruptThread (3) ؛ threadpoolutils.getInstance (). getThreadPool (). ScheduleAtfixedrate (InterruptthRead2،0،2 ، timeunit.seconds) ؛ Thread.sleep (5000) ؛ // إنهاء تشغيل سلسلة العرض T.Cancel (True) ؛ بينما (صواب) {}} Override public void run () {system.out.println ("هذا هو مؤشر ترابط" + num) ؛ }}سجل محاصر
عندما كان الملصق يستخدم الكود التالي ، فكر فجأة في كيفية إيقاف الموضوع من التشغيل عندما تحتاج مهمة التوقيت هذه إلى إيقاف.
threadpoolutils.getInstance ().
نظرًا لأن لدي مثل هذه الحاجة ، فلنناقش ذلك. بعد البحث عن معظم الوقت ، لم أتمكن من العثور على أي معلومات ذات صلة. كانوا جميعا تحليل متعمق لسباحة خيوط جافا. أو المتغيرات العالمية أو شيء من هذا القبيل ، لم يتم العثور على حل لإرضاء المؤلف.
نظرًا لعدم وجود مؤشر ترابط ، دعنا نلقي نظرة على رمز المصدر الأساسي لـ SCHELLEATFIXEDRATE لمعرفة ما هو عليه. كما هو متوقع ، رأيت التنفيذ المحدد لطريقة ScheduleAtFixedRate في الكود المصدر ووجدت أن قيمة الإرجاع الخاصة بها هي جدولة.
ScheduleDfuture <؟> ScheduleAtfixedRate (أمر Runnable ، initialdelay الطويل ، الفترة الطويلة ، وحدة timeUnit) {if (command == null || unit == null) رمي nullpointerxception () ؛ إذا (الفترة <= 0) رمي جديد غير unalfalArgumentException () ؛ ScheduleDfutureTask <Void> sft = new ScheduleDfutureTask <Void> (command ، null ، triggertime (initialDelay ، unit) ، unit.tonanos (period)) ؛ RunnablesCheduleDfuture <Void> t = decorateTask (command ، sft) ؛ sft.outerTask = t ؛ تأخير evenedexecute (t) ؛ العودة ر ؛ }ثم دعونا نلقي نظرة على ما هو داخل ScheduledFuture. لم يخيب ظن الملصق ، ورأيت هذا
إلغاء منطقي عام (Boolean MayinterrupruptIfrunning) {boolean coulded = super.cancel (mayinterrupruptifrunning) ؛ if (تم إلغاء && removeOncancel && heapindex> = 0) إزالة (هذا) ؛ إرجاع الإرجاع ؛} // قم بإزالة مؤشر الترابط الحالي من قائمة انتظار قائمة الانتظار العامة لإزالة (مهمة Runnable) {boolean readed = workqueue.remove (Task) ؛ tryTerMinate () ؛ // في حالة إيقاف التشغيل وإزالة الآن عودة فارغة ؛}دعنا نتحقق من Super.Cancel (Mayinterruptifrunning). نرى هذا.
// أوقف مؤشر الترابط الذي يعمل عن طريق استدعاء طريقة المقاطعة في سلسلة Boolean Public Cancel (May -Boolean ManeInterrupruprunning) {if (! حاول {// في حالة استدعاء مقاطعة رميات الاستثناء إذا (may may -Interruptifrunning) {try {thread t = runner ؛ if (t! = null) t.interrupt () ؛ } أخيرًا {// Final State Unsafe.putorderedInt (هذا ، StateOffset ، مقاطعة) ؛ }}} أخيرًا {FinishCompletion () ؛ } إعادة صواب ؛ }يتم حل جميع المشاكل هنا.
دعونا نلخص
هناك دائمًا حلول صعبة في المشاريع. عندما لا يكون من السهل العثور على Google ، فقد يكون ذلك وسيلة جيدة للبحث عن رمز مصدر JDK.