وظيفة الشرط هي توفير التحكم أكثر دقة في القفل. تعتبر طريقة AWAIT () في حالة مكافئة لطريقة WAIT () للكائن ، وطريقة الإشارة () في حالة ما يعادل طريقة الكائن () ، و islipall () في حالة ما يعادل طريقة الإخطار () للكائن. الفرق هو أن طرق WAIT () ، والإخطار () ، وإخطار () في الكائن مجمعة مع "قفل متزامن" (الكلمة الرئيسية المتزامنة) ؛ ويجب تجميع الحالة بـ "mutex"/"قفل المشاركة".
قائمة وظيفة الشرط
// يتسبب في انتظار الخيط الحالي حتى يتلقى إشارة أو يتم مقاطعة. يؤدي void في انتظار () // يتسبب في بقاء مؤشر الترابط الحالي في حالة انتظار قبل تلقي إشارة ، أو مقاطعة ، أو الوصول إلى وقت الانتظار المحدد. منطقية في انتظار (وقت طويل ، وحدة الوقت) // تتسبب في أن يكون الخيط الحالي في حالة انتظار حتى يتلقى إشارة ، أو يتم مقاطعة أو يصل إلى وقت الانتظار المحدد. منذ فترة طويلة في الانتظار (Nanostimeout الطويل) // يتسبب في أن يكون الخيط الحالي في حالة انتظار قبل تلقي الإشارة. void awaituninterruptly () // يتسبب في بقاء مؤشر الترابط الحالي في حالة انتظار حتى يتلقى إشارة ، أو يتم مقاطعة ، أو يصل إلى الموعد النهائي المحدد. Boolean Awaituntil (الموعد النهائي للتاريخ) // استيقظ موضوع انتظار. إشارة باطلة () // استيقظ جميع مؤشرات ترابط الانتظار. إشارة باطلة ()
مثال استخدام فئة الحالة
يحطم الشرط طرق شاشة الكائن (الانتظار ، والإخطار ، وإخطار) في كائنات مختلفة تمامًا بحيث من خلال الجمع بين هذه الكائنات مع أي تطبيق قفل ، يوفر كل كائن مجموعات انتظار متعددة (مجموعة الانتظار). من بينها ، يحل Lock محل استخدام الأساليب والبيانات المتزامنة ، ويستبدل الحالة استخدام طرق مراقبة الكائن. فيما يلي مثال مكتوب مسبقًا لتواصل مؤشر ترابط مع التنفيذ مع الشرط ، والرمز كما يلي:
الفئة العامة threadtest2 {public static void main (string [] args) {Final Business Business = new Business () ؛ مؤشر ترابط جديد (جديد RunNable () {Override public void run () {threadexecute (business ، "sub") ؛}}). start () ؛ threadexecute (الأعمال ، "main") ؛ } public static void threadexecute (الأعمال التجارية ، سلسلة threadtype) {for (int i = 0 ؛ i <100 ؛ i ++) {try {if ("main" .equals (threadtype)) {business.main (i) ؛ } آخر {business.sub (i) ؛ }} catch (interruptedException e) {E.PrintStackTrace () ؛ }}}} فئة الأعمال {private boolean bool = true ؛ قفل قفل خاص = جديد reentrantlock () ؛ حالة الحالة الخاصة = lock.newcondition () ؛ Public /*Synchronized* / void main (int loop) remrows interruptedException {lock.lock () ؛ جرب {بينما (bool) {inction.await () ؛ // this.wait () ؛ } لـ (int i = 0 ؛ i <100 ؛ i ++) {system.out.println ("thread main seq من" + i + "، حلقة" + loop) ؛ } bool = true ؛ Condition.Signal () ؛ // this.notify () ؛ } أخيرًا {lock.unlock () ؛ }} public /*synchronized* / void sub (int loop) remrows interruptedException {lock.lock () ؛ جرب {بينما (! bool) {inction.await () ؛ // this.wait () ؛ } لـ (int i = 0 ؛ i <10 ؛ i ++) {system.out.println ("sub thread seq من" + i + "، حلقة" + loop) ؛ } bool = false ؛ Condition.Signal () ؛ // this.notify () ؛ } أخيرًا {lock.unlock () ؛ }}} في حالة ، استبدل WAIT () بـ AWAIT () ، واستبدل الإخطار () بالإشارة () ، واستبدل الإخطار () بـ SignalAll (). يمكن تنفيذ طريقة الاتصال التقليدية للمواضيع. لاحظ هنا أن هذا الشرط مرتبط بالقفل. لإنشاء قفل ، يجب عليك استخدام طريقة NewCondition ().
وبهذه الطريقة ، لا يختلف الحالة عن اتصال الخيط التقليدي. قوة الشرط هي أنه يمكن أن تنشئ شروطًا مختلفة بين خيوط متعددة. فيما يلي قطعة رمز من واجهة برمجة التطبيقات لتوضيح.
الفئة probedbuffer {final lock lock = new reentrantlock () ؛ // قفل كائن الحالة النهائية notfull = lock.newcondition () ؛ // اكتب شرط مؤشر الترابط الشرط النهائي notempty = lock.newcondition () طابور*/؛ Public void put (Object x) remrows interruptedException {lock.lock () ؛ جرب {بينما (count == items.length) // إذا كانت قائمة الانتظار مليئة بـ notfull.await () ؛ // قم بحظر عناصر مؤشر ترابط الكتابة [putptr] = x ؛ // ississ (++ putptr == items.length) putptr = 0 ؛ أخيرًا {lock.unlock () ؛ }} الكائن العام take () رميات interruptedException {lock.lock () ؛ جرب {بينما (count == 0) // إذا كانت قائمة الانتظار فارغة notempty.await () ؛ // حظر كائن مؤشر ترابط القراءة x = العناصر [takeptr] ؛ // اختر القيمة إذا (++ takeptr == items.length) takeptr = 0 ؛ // index يقرأ الفهرس الأخير من قائمة الانتظار ، قم بتعيينه على 0 --- count ؛ } أخيرًا {lock.unlock () ؛ }}} هذه منطقة ذاكرة التخزين المؤقت في بيئة عمل متعددة الخيوط. توفر منطقة ذاكرة التخزين المؤقت طريقتين: وضع واتخاذ. وضعت لتخزين البيانات ، خذ هو استرداد البيانات ، وهناك قائمة انتظار ذاكرة التخزين المؤقت في الداخل. راجع الكود لمتغيرات محددة وأوصاف الأساليب. الوظائف التي تنفذها فئة منطقة ذاكرة التخزين المؤقت هذه: تخزين مؤشرات الترابط المتعددة بيانات واسترداد البيانات منها. الحد الأقصى لقيمة ذاكرة التخزين المؤقت التي يمكن أن تكون قائمة انتظار ذاكرة التخزين المؤقت (أولاً ، أولاً ، ثم في ، ثم الخروج) هي 100. عندما تصل القيمة المخزنة في قائمة انتظار ذاكرة التخزين المؤقت إلى 100 ، سيتم حظر مؤشر ترابط الكتابة وسيتم إيقاظ مؤشر ترابط القراءة. عندما تكون القيمة المخزنة في قائمة انتظار ذاكرة التخزين المؤقت 0 ، سيتم حظر مؤشر ترابط القراءة وسيتم إيقاظ مؤشر ترابط الكتابة. التحليل التالي لعملية تنفيذ الكود:
1. يقوم مؤشر ترابط الكتابة بتنفيذ ويدعو طريقة وضع ؛
2. لتحديد ما إذا كان العد هو 100 ، من الواضح أنه لا يوجد 100 ؛
3. مواصلة تنفيذ القيمة وإيداعها ؛
4. بعد تحديد موضع الفهرس المكتوب حاليًا ++ ، سواء كان مساوياً لـ 100. تعادل قيمة فهرس الكتابة إلى 0 و COUNT+1 ؛
5. استيقظ فقط واحدة من قوائم انتظار خيط القراءة ؛
6. قم بتنفيذ مؤشر ترابط القراءة واستدعاء طريقة أخذ ؛
7.
8. استيقظ فقط واحدة من قوائم انتظار خيط الكتابة.
هذه هي قوة ظروف متعددة. على افتراض أن قائمة انتظار ذاكرة التخزين المؤقت ممتلئة ، فإن الحظر هو بالتأكيد مؤشر ترابط الكتابة ، والاستيقاظ هو بالتأكيد موضوع القراءة. على العكس من ذلك ، فإن الحظر هو بالتأكيد موضوع القراءة ، والاستيقاظ هو بالتأكيد موضوع الكتابة. إذن ماذا سيحدث إذا كان هناك حالة واحدة فقط؟ قائمة انتظار ذاكرة التخزين المؤقت ممتلئة ، هذا القفل لا يعرف ما إذا كان مؤشر ترابط القراءة أو مؤشر ترابط الكتابة. إذا كان الاستيقاظ هو موضوع القراءة ، الجميع سعداء. إذا كان الاستيقاظ هو مؤشر ترابط الكتابة ، فقد تم إيقاظ الخيط وحظره مرة أخرى ، ثم يستيقظ مرة أخرى ، الأمر الذي يضيع الكثير من الوقت.