هذه المقالة هي ملخص للاستخدام الأساسي لـ Java MultiThreading.
ستشرح هذه المقالة الاستخدام الأساسي لـ Java Multithreading من الجوانب التالية:
كيفية استخدام multithreads
طريقتان لبدء موضوع
توفر Java طريقتان لاستخدام متعدد الخيوط. أحدهما هو كتابة فئة لروث مؤشر ترابط ، ثم الكتابة فوق طريقة التشغيل ، ثم استدعاء طريقة البدء لبدء مؤشر الترابط. في هذا الوقت ، ستقوم هذه الفئة بتشغيل الكود في طريقة التشغيل بالطريقة التي يتمتع بها مؤشر ترابط آخر. هناك طريقة أخرى تتمثل في كتابة فئة لتنفيذ الواجهة القابلة للتشغيل ، ثم تنفيذ تشغيل طريقة الواجهة ، ثم إنشاء كائن مؤشر ترابط ، واستخدم الفئة التي تنفذ الواجهة القابلة للتشغيل كمعلمة بناء ، وتمريرها إلى كائن مؤشر الترابط ، وأخيراً كائن مؤشر الترابط يستدعي طريقة البدء.
طريقة البدء هنا هي طريقة مع وظيفة بدء التشغيل ، والتي تستدعي داخليًا طريقة التشغيل. لذلك ، فقط عند استدعاء طريقة البدء ، سيتم بدء مؤشر ترابط آخر ، سيتم استدعاء طريقة التشغيل مباشرة ، أو تشغيلها في نفس الخيط ، بدلاً من التشغيل في مؤشر ترابط آخر
بالإضافة إلى ذلك ، تخبر طريقة البداية فقط الجهاز الظاهري بأنه يمكن بدء مؤشر الترابط ، مما يعني أن الخيط موجود في الحالة الجاهزة ، لكن هذا لا يعني أن المكالمة للبدء ستعمل على الفور. هذا يتطلب انتظار JVM لتحديد متى يتم تنفيذ الخيط. بمعنى آخر ، إذا كان هناك خيطان A و B ، فستبدأ المكالمات A أولاً ، وتبدأ المكالمات B لاحقًا ، فهذا لا يعني أن موضوع A يعمل أولاً ، ويتم تشغيل الموضوع B لاحقًا. يتم تحديد كل هذا بواسطة JVM ويمكن اعتباره بدء تشغيل عشوائي.
أدناه نستخدم الكود الفعلي لتوضيح طريقتين لبدء مؤشرات الترابط:
النوع الأول هو ترجيح الخيط
ExamplethRead الفئة العامة يمتد Thread {Override public void run () {super.run () ؛ System.out.println ("هذا هو امتحان ورث من الخيط") ؛ }}يمكن العثور على رمز الاختبار في فئة explethReadTest في دليل الاختبار
طريقة أخرى ، تنفذ واجهة Runnable
الطبقة العامة examplerUnable تنفس Runnable {public void run () {system.out.println ("هذا هو الفئة التي تنفذ الواجهة القابلة للتشغيل") ؛ }}بالنسبة لرمز الاختبار ، يمكنك رؤية فئة ExamplerUnableTest في دليل الاختبار.
كيفية الحصول على بعض المعلومات حول multithreading
بعد البدء في متعدد الخيوط ، نأمل في الحصول على بعض المعلومات حول موضوع بدء تشغيل بعض واجهات برمجة التطبيقات. توفر لنا JDK طريقة فئة مؤشرات ترابط للحصول على بعض المعلومات حول الموضوع.
احصل على اسم الموضوع
هذه الطرق هي طرق داخلية للخيط ، حتى نتمكن من تسمية هذه الأساليب بطريقتين. الأول هو أنه عندما يرث فئةنا الخيط لاستخدام الخيوط المتعددة ، يمكننا استخدام هذا للاتصال به. طريقة أخرى هي استدعاء هذه الطرق من خلال thread.currentThread (). ومع ذلك ، فإن هاتين الطريقتين مختلفتين في سيناريوهات الاستخدام المختلفة.
دعونا ننظر بإيجاز في استخدام طريقتين.
يتم استخدام thread.currentThread () ، الرمز كما يلي:
ExampleCurrentTrathread العام يمتد مؤشر الترابط {public exampleCurrentThread () {system.out.println ("طباعة طريقة المنشئ:" + thread.currentThRead (). getName ()) ؛ } Override public void run () {super.run () ؛ System.out.println ("طباعة طريقة التشغيل:" + thread.currentThread (). getName ()) ؛ }}رمز الاختبار كما يلي:
الفئة العامة exampleCurrentThReadTest يمتد testcase {public void testinit () يلقي الاستثناء {examplecurrentTherDhread thread = new exampleCurrentThread () ؛ } public void testrun () يلقي استثناء {examplecurrentTherD thread = new exampleCurrentThread () ؛ thread.start () ؛ thread.sleep (1000) ؛ }}النتائج كما يلي:
طباعة طريقة المنشئ: طباعة طريقة MainRun: طباعة طريقة البناء: MAIN
لماذا نستخدم thread.currentThRead () داخل exampleCurrentThread لعرض أن طريقة البناء تتم طباعتها على أنها رئيسية ، لأن thread.currentThread () تُرجع المعلومات التي يطلق عليها قطاع الرمز هذا الموضوع. من الواضح أن طريقة البناء يتم تنفيذها بواسطة الخيط الرئيسي ، ويتم تنفيذ طريقة التشغيل بواسطة الخيط الذي بدأناه من قبل أنفسنا. لأنه لم يتم تسميته ، فهو مؤشر ترابط الافتراضي.
بعد ذلك ، نلقي نظرة على الوراثة من الخيط ونطلق عليه بهذا.
الطبقة العامة ComplexCurrentTrathread يمتد الموضوع {public ComplexCurrentThRead () {system.out.println ("start ===================") ؛ System.out.println ("thread.currentThRead (). getName =" + thread.currentThRead (). getName ()) ؛ System.out.println ("this.getName () =" + this.getName ()) ؛ System.out.println ("End ================================================) ؛} Override Public Void Run () {super.run () ؛ System.out.println ("thread.currentThread ().رمز الاختبار كما يلي:
الطبقة العامة ComplexCurrentThReadTest يمتد testcase {public void testrun () يلقي الاستثناء {complexcurrentTherDhread thread = new ComplexCurrentThread () ؛ thread.setName ("byhieg") ؛ thread.start () ؛ thread.sleep (3000) ؛ }}النتائج كما يلي:
begin===========Thread.currentThread().getName=mainthis.getName()=Thread-0end===================== Run begin========Thread.currentThread().getName=byhiegthis.getName()=byhiegrun end===========
بادئ ذي بدء ، عند إنشاء الكائن ، لا يزال يتم تنفيذ المنشئ بواسطة مؤشر الترابط الرئيسي ، لذلك يحصل Thread.CurrentThread () على اسم مؤشر الترابط الرئيسي ، ولكن هذه الطريقة تشير إلى الكائن الذي يستدعي الطريقة ، أي معلومات مؤشر ترابط ComplexCurrentThread. لا يوجد اسم setName حتى الآن ، لذلك هو الاسم الافتراضي. ثم طريقة التشغيل هي إما thread.currentThRead () أو هذه المعلومات التي تُرجع معلومات الموضوع باستخدام مجموعة اسم Byhieg.
لذلك يشير Thread.CurrentTherD إلى معلومات مؤشر الترابط التي تنفذ على وجه التحديد كتلة الرمز هذه. يتم تنفيذ المنشئ بواسطة Main ، وطريقة التشغيل هي التي يبدأ مؤشر الترابط وتنفيذ مؤشر ترابط التشغيل. من وجهة النظر هذه ، تكون المعلومات التي يمكن أن تحصل عليها هذا غير دقيقة ، لأنه إذا قمنا بتنفيذ this.getName () في التشغيل ، ولكن يتم تشغيل طريقة التشغيل بواسطة مؤشر ترابط آخر ، لا يمكننا الحصول على معلومات المدينة الجديدة التي تعمل على تشغيل طريقة التشغيل من خلال this.getName. يمكن أن تحتوي فقط الفصول الدراسية التي ترث سلسلة رسائل على طرق مثل GetName ، وهي كارثة للغات الميزات الخاصة بـ Java التي لا تحتوي على ميراث متعددة. لجميع المعلومات حول المواضيع التي نريد الحصول عليها بعد ذلك ، نستخدم thread.currentThread () للاتصال بأجهزة API.
احصل على معرف الموضوع
اتصل بـ GetId للحصول على التعريف الفريد للموضوع. هذا هو نفس استخدام GetName أعلاه. لا يوجد شيء ليقوله. يمكنك إلقاء نظرة مباشرة على exampleDthread و Test Class ImputOdthReadTest.
تحديد ما إذا كان الموضوع يبقى
وظيفة الطريقة isalive () هي اختبار ما إذا كان الخيط نشطًا. ما يسمى الحالة النشطة يعني أن الخيط قد بدأ ولكنه لم ينتهي. وهذا هو ، بعد بدء الخيط ، يعتبر على قيد الحياة.
لنلقي نظرة على أمثلة محددة:
الطبقة العامة alivethread يمتد الموضوع {Override public void run () {super.run () ؛ System.out.println ("هل هو حي في طريقة التشغيل" + "" + thread.currentThRead (). isAlive ()) ؛ }}طريقة الاختبار كما يلي:
الطبقة العامة AlivethReadTest يمتد testcase {public void testrun () يلقي الاستثناء {alivethread thread = new alivethread () ؛ System.out.println ("start ==" + thread.isalive ()) ؛ thread.start () ؛ thread.sleep (1000) ؛ system.out.println ("end ==" + thread.isalive ()) ؛ thread.sleep (3000) ؛ }}النتائج كما يلي:
ابدأ == سواء كان ذلك صحيحًا في الطريقة الخاطئة == خطأ
يمكننا أن نجد أنه قبل البدء ، يعتبر الخيط غير محظوظ ، ثم عندما يعمل ، يكون حيًا. عندما يتم تنفيذ طريقة التشغيل ، تعتبر غير مستقرة.
كيفية إيقاف الموضوع
تحديد ما إذا كان الموضوع قد انتهى
يوفر JDK بعض الطرق لتحديد ما إذا كان الخيط قد تم إنهاء - IsInterrupted () ومقاطع ()
كيفية إيقاف المواضيع
هذه طريقة أكثر أهمية في الحصول على معلومات مؤشر الترابط ، لأنها مرتبطة بطريقة إنهاء مؤشرات الترابط. اسمحوا لي أولاً أن أتحدث عن عدة طرق لإنهاء المواضيع:
لن أتحدث عن الطريقة الأولى ، تم التخلي عن طريقة STOP () الثانية لأن الأسباب التالية قد تحدث:
للحصول على أمثلة محددة ، يمكنك رؤية StopLockThread و Test Class StoplockThreadTest
النوع الثالث هو طريقة الإنهاء الموصى بها حاليًا ، والاتصال بمقاطعة ، ثم تحديد ما إذا كان سيتم إنهاء في طريقة التشغيل. هناك طريقتان للحكم على الإنهاء. إحداها هي الطريقة الثابتة المقاطعة () من فئة الخيط ، والآخر هو طريقة عضو مؤشر الترابط IsInterredred (). هناك فرق بين هاتين الطريقتين. ستقوم الطريقة الأولى تلقائيًا بإعادة ضبط الحالة. إذا تم استدعاء المقاطعة () مرتين على التوالي ، إذا كان هذا خطأ في المرة الأولى ، في المرة الثانية التي يجب أن تكون صحيحة. و isInterrupted () لن.
الأمثلة على النحو التالي:
الفئة العامة exampleIntRuptTreThread يمتد Thread {Override public void run () {super.run () ؛ حاول {for (int i = 0 ؛ i <50000000 ؛ i ++) {if (interrupted ()) {system.out.println ("إنها بالفعل حالة توقف ، أريد الخروج") ؛ رمي جديد interruptedException ("توقف ......") ؛ } system.out.println ("i =" + (i + 1)) ؛ }} catch (interruptedException e) {system.out.println ("stop smooth") ؛ }}}رمز الاختبار كما يلي:
الفئة العامة exampleIntRupruptTreadTest يمتد testcase {public void testrun () يلقي الاستثناء {exampleinterruptthread thread = new exampleinterruptthread () ؛ thread.start () ؛ thread.sleep (1000) ؛ thread.Interrupt () ؛ }}الطريقة الرابعة هي نفس الطريقة الثالثة. الفرق الوحيد هو استبدال الاستثناء الذي تم إلقاؤه في الكود أعلاه مع الإرجاع. ما زلت أحب رمي الاستثناءات. هناك العديد من أشكال المعالجة هنا ، مثل طباعة المعلومات أو إغلاق أو التقاط المورد ثم رميها إلى الطبقة العليا مرة أخرى.
لاحظ أن الاستثناء الذي ألقيناه أعلاه هو مقاطع. هنا نتحدث بإيجاز عن أسباب إنشاء هذا الاستثناء. في حالة نوم الخيط الأصلي ، استدعاء المقاطعة لإنهاء الخيط ، أو إنهاء الخيط أولاً ثم اترك مؤشر الترابط ينام.
كيفية إيقاف الموضوع
يتم توفير الطريقتين التاليتين في JDK لتوقف الخيوط واستعادة المواضيع.
هاتان الطريقتين يتم التخلي عنها مثل طريقة الإيقاف ، واستخدامهما هو نفسه التوقف ، وملعون الخيوط بوحشية واستعادة المواضيع. الأسباب الرئيسية وراء التخلي عن هاتين الطريقتين هي:
بعض الاستخدامات الأخرى من المواضيع
بعض الاستخدامات الأساسية الأخرى للمواضيع هي كما يلي:
تنازلات الموضوع
يوفر JDK طريقة العائد () لجعل مؤشر الترابط يتخلى عن مورد وحدة المعالجة المركزية الحالية وإعطائه مهام أخرى لاحتلال وقت وحدة المعالجة المركزية ، ولكن هذا أيضًا شيء عشوائي. من الممكن أن تستغرق شريحة الوقت بعد التخلي عن الموارد.
للحصول على أمثلة محددة ، يرجى الرجوع إلى exampleyieldthread و test class exampleyieldthreadtest
حدد أولوية المواضيع
يمكننا تعيين أولوية مؤشرات الترابط للسماح لوحدة المعالجة المركزية قدر الإمكان لإرسال موارد التنفيذ إلى مؤشرات الترابط ذات أولوية أعلى. تحدد Java 1-10 10 مستويات ذات أولوية ، وهناك ثلاثة متغيرات ثابتة لتوفير ثلاثة مستويات ذات أولوية:
/*** الحد الأدنى للأولوية التي يمكن أن يكون لها مؤشر ترابط. */ public final static int min_priority = 1 ؛ /*** الأولوية الافتراضية التي يتم تعيينها إلى مؤشر ترابط. */ public final static int norm_priority = 5 ؛ /*** أقصى الأولوية التي يمكن أن يكون لها مؤشر ترابط. */ public final static int max_priority = 10 ؛
يمكننا تعيين أولوية الخيط من خلال setPriority ، ويمكننا أن تمر مباشرة في ثلاثة متغيرات ثابتة للاستئناف ، أو تمريرها مباشرة في الأرقام 1-10. بعد الإعداد ، سيكون لخيط أولويات مختلفة. ماذا يحدث إذا لم نضع الأولوية؟
وراثي أولوية المواضيع. إذا بدأنا الموضوع B في الموضوع A ، فإن AB لديه نفس الأولوية. بشكل عام ، عندما نبدأ خيط في الخيط الرئيسي ، لدينا أولوية متسقة مع الخيط الرئيسي. أولوية الموضوع الرئيسي هي 5 بشكل افتراضي.
فيما يلي بعض القواعد للأولوية:
حارس الموضوع
يوفر JDK طريقة setDaemon لتعيين مؤشر ترابط ليصبح مؤشر ترابط الخفي. تتمثل خاصية خيوط الخفيون في أنه بعد تنفيذ خيوط غير أخرى غير Daemon ، سيتم تدمير خيوط Daemon تلقائيًا. مثال نموذجي هو إعادة التدوير GC.
لمزيد من التفاصيل ، يمكنك رؤية exampledaemonthread و exampleDaemonThreadTest.
لخص
تلخص هذه المقالة بشكل أساسي بعض الاستخدامات الأساسية لخيوط Java ، ويتم تضمينها في المقالة الثانية حول سلامة الخيط والمزامنة.
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون محتوى هذه المقالة من بعض المساعدة في دراسة أو عمل الجميع. آمل أيضًا دعم wulin.com أكثر!