1. مقدمة
هذا الملخص لفهم التواصل بين المواضيع بتنسيق Java متعدد الخيوط يناقش بشكل أساسي التواصل بين المواضيع في مصنفة رمز مع النص ، لذلك قمت بإزالة بعض رموز المثال في الكتاب.
2. طريقة الاتصال بين المواضيع
① المزامنة
يشير المزامنة المذكورة هنا إلى مؤشرات ترابط متعددة باستخدام الكلمة الرئيسية المتزامنة لتحقيق التواصل بين مؤشرات الترابط.
مثال مرجعي:
الفئة العامة myObject {متزامنة public void methoda () {// افعل شيئًا ....} متزامن methodbed public void () {// قم بشيء آخر}} يمتد Threada العام public threada thread {private myobject object ؛ // dish the building override public run () {super.run () ؛ Object.Methoda () ؛ }} الفئة العامة threadb يمتد مؤشر الترابط {private myobject object ؛ // حذف المُنشئ void public run () {super.run () ؛ object.methodb () ؛ }} الفئة العامة Run {public static void main (string [] args) {myObject Object = new myobject () ؛ // موضوع A و Thread B امسك نفس الكائن: Object threada a = new threada (كائن) ؛ threadb b = threadb جديد (كائن) ؛ A.Start () ؛ B.Start () ؛ }}نظرًا لأن الخيط A و Thread B يحملان كائن كائن فئة MyObject نفسها ، على الرغم من أن هذين الخيطين يحتاجان إلى استدعاء طرق مختلفة ، يتم تنفيذهما بشكل متزامن. على سبيل المثال ، يحتاج مؤشر الترابط B إلى الانتظار حتى يتمكن مؤشر الترابط A لتنفيذ طريقة Methoda () قبل أن يتمكن من تنفيذ طريقة MethodB (). وبهذه الطريقة ، يدرك الموضوع A و Thread B التواصل.
هذه الطريقة هي في الأساس اتصال "الذاكرة المشتركة". تحتاج مؤشرات الترابط المتعددة إلى الوصول إلى نفس المتغير المشترك ، ويمكن لأي من يحصل على القفل (يحصل على حقوق الوصول) تنفيذه.
② طريقة الاقتراع
الرمز كما يلي:
استيراد java.util.arraylist ؛ استيراد java.util.list ؛ الفئة العامة mylist {قائمة خاصة <string> list = new ArrayList <String> () ؛ public void add () {list.add ("elements") ؛ } public int size () {return list.size () ؛ }} import MyList.mylist ؛ public class threada يمتد thread {private MyList List ؛ public threada (MyList List) {super () ؛ this.list = list ؛ } Override public void run () {try {for (int i = 0 ؛ i <10 ؛ i ++) {list.add () ؛ System.out.println ("إضافة" + (i + 1) + "عناصر") ؛ thread.sleep (1000) ؛ }} catch (interruptedException e) {E.PrintStackTrace () ؛ }}} استيراد myList.Mylist ؛ فئة public threadb يمتد Thread {private MyList List ؛ threadb العامة (قائمة MyList) {super () ؛ this.list = list ؛ } Override public void run () {try {when (true) {if (list.size () == 5) {system.out.println ("== 5 ، thread b جاهز للخروج") ؛ رمي جديد interruptedException () ؛ }}} catch (interruptedException e) {E.PrintStackTrace () ؛ }}} import mylist.mylist ؛ import extthread.threada ؛ import extthread.threadb ؛ test strace public {public static void main (string [] args) {myList service = new MyList () ؛ threada a = new threada (service) ؛ A.SetName ("A") ؛ A.Start () ؛ threadb b = new threadb (service) ؛ B.SetName ("B") ؛ B.Start () ؛ }}وبهذه الطريقة ، يغير مؤشر الترابط A الشروط باستمرار ، ويكتشف Threadb باستمرار ما إذا كان هذا الشرط (list.size () == 5) صحيحًا من خلال البيان ، وبالتالي تحقيق التواصل بين المواضيع. لكن هذه الطريقة ستضيع موارد وحدة المعالجة المركزية. السبب في أن الموارد تضيع هو أنه عندما يقوم جدولة JVM بتسليم وحدة المعالجة المركزية إلى مؤشر الترابط B للتنفيذ ، فإنه لا يقوم بأي عمل "مفيد" ، ولكنه يختبر باستمرار ما إذا كانت هناك حالة معينة صحيحة. إنه مشابه في الحياة الحقيقية ، يستمر شخص ما في النظر إلى ما إذا كان الهاتف يأتي على شاشة هاتفه المحمول ، بدلاً من: القيام بشيء آخر ، عندما يأتي الهاتف ، فإن الرنين سوف يخطره أن الهاتف قادم.
③ wait/إعلام الآلية
الرمز كما يلي:
استيراد java.util.arraylist ؛ استيراد java.util.list ؛ الفئة العامة myList {قائمة ثابتة خاصة <string> list = new ArrayList <String> () ؛ void static add () {list.add ("anystring") ؛ } size int static public () {return list.size () ؛ }} الفئة العامة يمتد Threada thread {private Object Lock ؛ public threada (قفل الكائن) {super () ؛ this.lock = قفل ؛ } Override public void run () {try {synchronized (lock) {if (mylist.size ()! = 5) {system.out.println ("انتظر ابدأ" + system.currentTimEmillis ()) ؛ lock.wait () ؛ System.out.println ("Wait End" + System.CurrentTimeMillis ()) ؛ }}} catch (interruptedException e) {E.PrintStackTrace () ؛ }}} فئة public threadb يمتد مؤشر الترابط {قفل الكائن الخاص ؛ public threadb (قفل الكائن) {super () ؛ this.lock = قفل ؛ } Override public void run () {try {synchronized (lock) {for (int i = 0 ؛ i <10 ؛ i ++) {myList.add () ؛ if (myList.size () == 5) {lock.notify () ؛ System.out.println ("إخطار") ؛ } system.out.println ("إضافة" + (i + 1) + "عناصر!") ؛ thread.sleep (1000) ؛ }}} catch (interruptedException e) {E.PrintStackTrace () ؛ }}} الفئة العامة Run {public static void main (string [] args) {try {object lock = new Object () ؛ threada a = new threada (lock) ؛ A.Start () ؛ thread.sleep (50) ؛ threadb b = threadb جديد (قفل) ؛ B.Start () ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ }}}يجب أن ينتظر الموضوع A شرطًا معينًا قبل إجراء العملية. يضيف الموضوع B عناصر إلى القائمة ويغير حجم القائمة.
كيف تتواصل A و B؟ بمعنى آخر ، كيف يعرف الموضوع أن القائمة. size () هو بالفعل 5؟
هنا نستخدم طرق Wait () وعلم () طرق فئة الكائن.
عندما لا يتم تلبية الشرط (list.size ()! = 5) ، فإن سلسلة المكالمات A WAIT () للتخلي عن وحدة المعالجة المركزية ودخول حالة الحظر. --- لا تأخذ وحدة المعالجة المركزية مثل الاقتراع أثناء الاقتراع
عند استيفاء الشرط ، يقوم مؤشر الترابط B بإخطار () بإخطار مؤشر الترابط أ.
ميزة واحدة من هذه الطريقة هي أنه تم تحسين استخدام وحدة المعالجة المركزية.
ولكن هناك بعض العيوب: على سبيل المثال ، يتم تنفيذ مؤشر الترابط B أولاً ، ويضيف 5 عناصر في وقت واحد ومكالمات إخطار () لإرسال إشعار ، وخيط لا يزال ينفذ ؛ عندما يتم تنفيذ الموضوع A والمكالمات WAIT () ، فلن يتم إيقاظه أبدًا. لأن الموضوع B قد أصدر بالفعل إشعارًا ولن يصدر أي إشعار في المستقبل. هذا يدل على أن الإشعار مبكر جدًا وسيعطل منطق تنفيذ البرنامج.
إن المقالة أعلاه تتفهم بعمق طريقة الاتصال بين مؤشرات الترابط متعددة الخيوط Java هي كل المحتوى الذي أشاركه معك. آمل أن يعطيك مرجعًا وآمل أن تتمكن من دعم wulin.com أكثر.