هذه المقالة يدرس بشكل أساسي القضايا المتعلقة بخيوط الخلفية في جافا ، على النحو التالي.
لم أسمع به من قبل أن يكون هناك خيوط خلفية في جافا. بشكل عام ، يتضمن JVM (الجهاز الظاهري Java) عمومًا نوعين من مؤشرات الترابط ، وهما مؤشر ترابط المستخدم وخيط الخلفية. يشير ما يسمى بخيط الخفيون إلى مؤشر ترابط يوفر خدمة شائعة في الخلفية عند تشغيل البرنامج ، وهذا الموضوع ليس جزءًا لا غنى عنه من البرنامج. لذلك ، عندما تنتهي جميع المواضيع غير الخلفية ، فهذا يكون ، عندما تنتهي مؤشرات ترابط المستخدم ، ينتهي البرنامج. في الوقت نفسه ، سوف يقتل جميع خيوط الخلفية في هذه العملية. على العكس ، طالما أن أي مؤشرات ترابط غير خلفية لا تزال قيد التشغيل ، فلن ينتهي البرنامج. من الأفضل تنفيذ Main () من مؤشر ترابط غير تعزز.
استنادًا إلى هذه الميزة ، عندما يخرج جميع مؤشرات ترابط المستخدم في الجهاز الظاهري من التشغيل ، لا يحتوي مؤشر ترابط Daemon على كائنات خدمة ، يخرج JVM.
تم شرح ذلك في رمز مصدر JDK.
* يمثل هذا الموضوع إما {linkplain #isdaemon daemon}
* أو موضوع المستخدم. يخرج الجهاز الظاهري Java عندما يكون الوحيد
* المواضيع الجارية كلها مؤشرات الترابط الخفي.
1. شروط لبدء موضوع الخلفية:
/*يجب استدعاء طريقة setDaemon () قبل بدء تشغيل الخيط لتعيين هذا الموضوع كخيط خلفية. * في هذا البرنامج ، بعد إدخال سلسلة ، سيتوقف مؤشر الترابط الرئيسي عن التشغيل* ثم لا يوجد مؤشر ترابط للمستخدم يمكنه تشغيله في البرنامج. لذلك سيتم إيقاف موضوع الخلفية * سيتم إيقاف JVM ، ويمكن للقراء المهتمين أن يجربوا بنفسك */فئة عامة Daemonrunner تنفذ Runnable {Override Public Void Run () {بينما (صحيح) {for (int i = 0 ؛ i <3 ؛ i ++) Daemon = Thread New Thread (New DaemonRunner ()) ؛ daemon.setdaemon (true) ؛ Daemon.Start () ؛ Scanner S = new Scanner (System.in) ؛ String = S.NextLine () ؛ Runtime.getRuntime (). {timeUnit.milliseconds.sleep (50) ؛} catch (interruptedException e) {E.PrintStackTrace () ؛}}}) ؛}}2. جميع المواضيع التي بدأت في مؤشر ترابط الخلفية تنتمي إلى مؤشر ترابط الخلفية. على الرغم من أنك لا تحدد صراحة أنها مؤشرات ترابط الخلفية ، إلا أنها بالفعل مؤشرات ترابط الخلفية.
/* يمكنك تحديد ما إذا كان مؤشر الترابط هو مؤشر ترابط الخلفية عن طريق استدعاء طريقة ISDaemon (). إذا كان مؤشر ترابط الخلفية ، * يتم ضبط أي مؤشر ترابط يقوم بإنشائه تلقائيًا على مؤشر ترابط الخلفية * في هذا المثال ، يتم ضبط مؤشر ترابط الخفي على وضع الخلفية ثم يستمد العديد من مؤشرات الترابط للأطفال. لا يتم ضبط هذه الخيوط على وضع الخلفية * ، لكنها بالفعل مؤشرات ترابط الخلفية. بعد ذلك ، يدخل مؤشر ترابط Daemon إلى حلقة Infinite ويدعو طريقة العائد في الحلقة* لتسليم عنصر التحكم إلى مؤشرات الترابط أو العمليات الأخرى*/Class Daemon Direments Runnable {Private Thread [] t = new thread [10] daemonspawn ()) ؛ t [i] {thread.yield () ؛}}} class daemonspawn تنفذ Runnable {Override public void run () {بينما (True) {thread.yield () ؛ daemon ()) ؛ d.setdaemon (true) ؛ d.start () ؛ system.out.println ("d.isdaemon () =" + d.isdaemon ()) ؛ حاول {timeunit.seconds.sleep (1) ؛ // اترك الخيط في خلفية البدء يحصل على وقت تنفيذ معين. } catch (interruptedException e) {E.PrintStackTrace () ؛}}}نتائج التنفيذ النهائية هي كما يلي:
d.isdaemon () = صواب
Daemonspawn 0started
daemonspawn 1started
daemonspawn 2started
daemonspawn 3started
Daemonspawn 4started
Daemonspawn 5started
Daemonspawn 6started
Daemonspawn 7started
Daemonspawn 8started
Daemonspawn 9started
T [0]. iSdaemonTrue
T [1] .isdaemontrue
T [2]. iSdaemonTrue
T [3] .isdaemontrue
T [4] .isdaemontrue
T [5] .isdaemontrue
T [6] .isdaemontrue
T [7]. iSdaemonTrue
T [8] .isdaemontrue
T [9] .isdaemontrue
3. حدد كائن ThreadFactory عن طريق تحديد طريقة Executors.newCachedThreadPool() . وبهذه الطريقة ، يمكننا أيضًا تعيين الخيط الذي نريد أن نبدأ كخيط خلفية.
/* في هذا المثال ، بالنسبة لهذا المُنشئ الثابت: Executors.NewCachedThreadPool (New DaemonThreadFactory ()* يمكننا تمرير كائن ThreadFactory ، حتى نتمكن من تعيين مؤشر الترابط الذي نريد أن نبدأه كخيط خلفية من خلال هذا الطريقة* يجب أن يكون ذلك. الخيط (R) ؛ T.Setdaemon (صحيح) ؛ إرجاع T ؛}/* في هذا المثال ، في الطريقة الرئيسية ، سيتم استدعاء الطريقة المعتادة في الطريقة الرئيسية أولاً ، سوف ينهي الخط الرئيسي التشغيل. (InterruptedException e) {system.out.println ("Interrupted") ؛}} الفراغ الثابت العام (String [] args) {executorService exec = executors. daemonfromfactory ()) ؛} system.out.println ("All Dameons chation") ؛ حاول {timeUnit.milliseconds.sleep (500) ؛} catch (interruptedException e) {eprintstacktrace () ؛}}}نتيجة الإخراج النهائي هي:
بدأت جميع السيدة
Thread [Thread-3،5 ، main] concurrency.daemonfromfactory@56214c1
Thread [thread-2،5 ، main] concurrency.daemonfromfactory@5724147d
Thread [thread-0،5 ، main] concurrency.daemonfromfactory@144fe080
Thread [Thread-1،5 ، main] concurrency.daemonfromfactory@104fa29e
Thread [Thread-8،5 ، Main] concurrency.daemonfromfactory@5b069a7f
Thread [Thread-9،5 ، Main] Concurrency.daemonfromfactory@1a7288d1
Thread [Thread-7،5 ، Main] concurrency.daemonfromfactory@25144c3e
Thread [Thread-4،5 ، Main] concurrency.daemonfromfactory@288523d
Thread [Thread-6،5 ، Main] Concurrency.daemonfromfactory@1edae2a8
Thread [Thread-5،5 ، Main] concurrency.daemonfromfactory@626007aa
Thread [Thread-3،5 ، main] concurrency.daemonfromfactory@56214c1
Thread [thread-2،5 ، main] concurrency.daemonfromfactory@5724147d
Thread [Thread-6،5 ، Main] Concurrency.daemonfromfactory@1edae2a8
Thread [Thread-5،5 ، Main] concurrency.daemonfromfactory@626007aa
Thread [Thread-4،5 ، Main] concurrency.daemonfromfactory@288523d
Thread [Thread-9،5 ، Main] Concurrency.daemonfromfactory@1a7288d1
Thread [Thread-7،5 ، Main] concurrency.daemonfromfactory@25144c3e
Thread [Thread-8،5 ، Main] concurrency.daemonfromfactory@5b069a7f
Thread [Thread-1،5 ، main] concurrency.daemonfromfactory@104fa29e
Thread [thread-0،5 ، main] concurrency.daemonfromfactory@144fe080
Thread [thread-2،5 ، main] concurrency.daemonfromfactory@5724147d
Thread [Thread-3،5 ، main] concurrency.daemonfromfactory@56214c1
Thread [Thread-6،5 ، Main] Concurrency.daemonfromfactory@1edae2a8
Thread [Thread-1،5 ، main] concurrency.daemonfromfactory@104fa29e
Thread [thread-0،5 ، main] concurrency.daemonfromfactory@144fe080
Thread [Thread-7،5 ، Main] concurrency.daemonfromfactory@25144c3e
Thread [Thread-8،5 ، Main] concurrency.daemonfromfactory@5b069a7f
Thread [Thread-5،5 ، Main] concurrency.daemonfromfactory@626007aa
Thread [Thread-9،5 ، Main] Concurrency.daemonfromfactory@1a7288d1
Thread [Thread-4،5 ، Main] concurrency.daemonfromfactory@288523d
Thread [thread-2،5 ، main] concurrency.daemonfromfactory@5724147d
Thread [Thread-3،5 ، main] concurrency.daemonfromfactory@56214c1
Thread [Thread-8،5 ، Main] concurrency.daemonfromfactory@5b069a7f
Thread [Thread-7،5 ، Main] concurrency.daemonfromfactory@25144c3e
Thread [Thread-4،5 ، Main] concurrency.daemonfromfactory@288523d
Thread [Thread-6،5 ، Main] Concurrency.daemonfromfactory@1edae2a8
Thread [Thread-1،5 ، main] concurrency.daemonfromfactory@104fa29e
Thread [thread-0،5 ، main] concurrency.daemonfromfactory@144fe080
Thread [Thread-9،5 ، Main] Concurrency.daemonfromfactory@1a7288d1
Thread [Thread-5،5 ، Main] concurrency.daemonfromfactory@626007aa
Thread [Thread-3،5 ، main] concurrency.daemonfromfactory@56214c1
Thread [thread-2،5 ، main] concurrency.daemonfromfactory@5724147d
Thread [Thread-8،5 ، Main] concurrency.daemonfromfactory@5b069a7f
4. أولاً وقبل كل شيء ، يجب أن تدرك أنه في حالة خروج مؤشر ترابط المستخدم فجأة ، سيقوم مؤشر ترابط الخلفية بإنهاء طريقة التشغيل الخاصة به دون تنفيذ البند الأخير.
/* عند الاتصال بهذا البرنامج ، سترى أنه لن يتم تنفيذ البند الأخير ، ولكن إذا قمت بتعليق المكالمة على Setdaemon () ، فسترى أنه سيتم تنفيذ البند أخيرًا.* هذا السلوك صحيح. حتى لو كنت لا تريد هذا السلوك بناءً على الوعد الذي قدمته أمامك أخيرًا. ولكن هذا هو الحال. عندما ينتهي الخيط الأخير غير الخلفي ، سيتوقف مؤشر ترابط الخلفية فجأة. لأنه بمجرد خروج Main () ، ستغلق JVM على الفور جميع المواضيع * في الخلفية. نظرًا لأنه لا يمكنك إغلاق خيوط الخلفية بطريقة أنيقة ، فهي بالكاد فكرة جيدة. عادةً ما يكون المنفذون غير المباريون طريقة أفضل * ، لأنه يمكن إغلاق جميع المهام التي يسيطر عليها المنفذ في نفس الوقت. */class adaemon تنفذ Runnable {Override public void run () {system.out.println ("stip adaemon") ؛ جرب {timeUnit.Seconds.sleep (1) ؛ } catch (interruptedException e) {system.out.println ("الخروج عبر InterruptedException") ؛ } أخيرًا {system.out.println ("هذا يجب أن يعمل دائمًا؟") ؛ }}} الفئة العامة daemonsdontrunfinally {public static void main (string [] args) {thread t = new thread (new Adaemon ()) ؛ T.SetDaemon (صواب) ؛ T.Start () ؛ }} نتائج الإخراج النهائية هي كما يلي:
بدء adaemon
ومع ذلك ، إذا أصبح الموقف هو الموقف التالي ، فستكون نتائج الإخراج مختلفة مرة أخرى:
class adaemon تنفذ Runnable {Override public void run () {system.out.println ("start Adaemon") ؛ جرب {timeUnit.Seconds.sleep (1) ؛ } catch (interruptedException e) {system.out.println ("الخروج عبر InterruptedException") ؛ } أخيرًا {system.out.println ("هذا يجب أن يعمل دائمًا؟") ؛ }}} الفئة العامة daemonsdontrunfinally {public static void main (string [] args) {thread t = new thread (new Adaemon ()) ؛ T.SetDaemon (صواب) ؛ T.Start () ؛ جرب {timeUnit.Seconds.sleep (1) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ }}}نظرًا لأن الخيط الرئيسي لا يخرج فجأة ، فإن مؤشر ترابط الخلفية يحصل على وقت التنفيذ أثناء نوم الخيط الرئيسي ، وبالتالي فإن النتيجة النهائية للطباعة هي:
بدء adaemon
هذا يجب أن يعمل دائما؟
ما سبق هو كل محتوى هذه المقالة حول تحليل مثيلات خيط الخلفية في جافا ، وآمل أن يكون مفيدًا للجميع. يمكن للأصدقاء المهتمين الاستمرار في الرجوع إلى الموضوعات الأخرى ذات الصلة على هذا الموقع. إذا كانت هناك أي أوجه قصور ، فيرجى ترك رسالة لإشارةها. شكرا لك يا أصدقائك لدعمكم لهذا الموقع!