تنازلات الموضوع: العائد ()
الغرض من العائد () هو الاستسلام. يمكن أن يسمح للموضوع الحالي بالدخول إلى "الحالة الجاهزة" من "الحالة الجارية" ، بحيث يمكن أن تحصل مؤشرات ترابط الانتظار الأخرى ذات نفس الأولوية على حقوق التنفيذ ؛ ومع ذلك ، لا يمكن أن يضمن أنه بعد العائد على المكالمات الحالية () ، ستحصل مؤشرات الترابط الأخرى ذات نفس الأولوية على حقوق التنفيذ ؛ قد يكون أيضًا أن الخيط الحالي يدخل "حالة الجري" ويستمر في العمل!
مثال:
Class Threada Extends Thread {public threada (اسم السلسلة) {super (name) ؛ } Runchronised void Run () {for (int i = 0 ؛ i <10 ؛ i ++) {system.out.printf ("٪ s [٪ d]: ٪ d/n" ، this.getName () ، this.getPriority () ، i) ؛ // عندما يتم تقسيمها على 4 ، استدعاء العائد إذا (i ٪ 4 == 0) thread.yield () ؛ }}} الفئة العامة العائد {public static void main (string [] args) {threada t1 = new threada ("t1") ؛ threada t2 = new threada ("t2") ؛ t1.start () ؛ t2.start () ؛ }} (مرة واحدة) نتيجة العملية:
T1 [5]: 0T2 [5]: 0T1 [5]: 1T1 [5]: 2T1 [5]: 3T1 [5]: 4T1 [5]: 5T1 [5]: 6T1 [5]: 7T1 [5]: 8T1 [5]: 9T2 [5]: [5]: 6T2 [5]: 7T2 [5]: 8T2 [5]: 9
وصف النتائج:
عندما يمكن إجراء "Thread T1" بواسطة 4 ، فإنه لا يتحول إلى "Thread T2". يوضح هذا أنه على الرغم من أن العائد () يمكن أن يسمح لرسائل الرسائل بالدخول إلى "الحالة الجاهزة" من "حالة الجري" ، فإنها لا تسمح بالضرورة بمواضيع أخرى بالحصول على حقوق تنفيذ وحدة المعالجة المركزية (على سبيل المثال ، تدخل مؤشرات الترابط الأخرى "الحالة الجارية") ، حتى لو كان هذا "مؤشر الترابط الآخر" له نفس أولوية مؤشر الترابط حاليًا ().
مقارنة العائد () وانتظر ():
نحن نعلم أن وظيفة WAIT () هي السماح للمعلومات الحالية بالدخول إلى حالة "الانتظار (حظر) من" حالة الجري "وأيضًا إطلاق قفل المزامنة. وظيفة العائد () هي الاستسلام ، مما سيؤدي أيضًا إلى ترك الخيط الحالي" حالة الجري ". خلافاتهم هي:
(1) WAIT () هو السماح لخيط مؤشر الترابط بإدخال "Wait (حظر) حالة" من "حالة الجري" ، في حين أن عدم العائد () هو السماح للمعلومات بإدخال "الحالة الجاهزة" من "الحالة الجارية".
(2) WAIT () هو قفل المزامنة سيؤدي إلى تحرير الكائن الذي يحتفظ به ، في حين أن طريقة العائد () لن تطلق القفل.
يوضح المثال التالي أن العائد () لن يطلق القفل:
الطبقة العامة العائد {private static object obj = new Object () ؛ public static void main (string [] args) {threada t1 = new threada ("t1") ؛ threada t2 = new threada ("t2") ؛ t1.start () ؛ t2.start () ؛ } static class threada يمتد thread {public threada (اسم السلسلة) {super (name) ؛ } public void run () {// get synchronized (obj) {for (int i = 0 ؛ i <10 ؛ i ++) {system.out.printf ("٪ s [٪ d]: ٪ d/n" ، this.getName () ، this.getPriority () ، i) ؛ // عندما يتم تقسيمها على 4 ، استدعاء العائد إذا (i ٪ 4 == 0) thread.yield () ؛ }}}}}} (مرة واحدة) النتيجة:
T1 [5]: 0T1 [5]: 1T1 [5]: 2T1 [5]: 3T1 [5]: 4T1 [5]: 5T1 [5]: 6T1 [5]: 7T1 [5]: 8T1 [5]: 9T2 [5]: 0T2 [5]: [5]: 6T2 [5]: 7T2 [5]: 8T2 [5]: 9
وصف النتائج:
يتم تشغيل خيطين T1 و T2 في الخيط الرئيسي الرئيسي. سيشير T1 و T2 إلى قفل المزامنة لنفس الكائن في التشغيل () ، أي متزامن (OBJ). أثناء عملية T1 ، على الرغم من أنها ستدعو thread.yield () ؛ لن تحصل T2 على حقوق تنفيذ وحدة المعالجة المركزية. لأن T1 لا يطلق "القفل المتزامن الذي يحتفظ به OBJ"!
موضوع النوم: النوم ()
يتم تعريف النوم () في thread.java.
تتمثل وظيفة النوم () في السماح للخيط الحالي بالنوم ، أي أن الخيط الحالي سوف يدخل من "حالة الجري" إلى "حالة النوم (الحظر)". سيحدد النوم () وقت النوم ، وسيكون وقت النوم في الخيط أكبر من وقت النوم ؛ عندما يتم إيقاظ الخيط مرة أخرى ، سيتغير من "حالة حظر" إلى "حالة جاهزة" ، في انتظار موعد تنفيذ وحدة المعالجة المركزية.
مثال:
Class Threada Extends Thread {public threada (اسم السلسلة) {super (name) ؛ } runnchronized void run () {try {for (int i = 0 ؛ i <10 ؛ i ++) {system.out.printf ("٪ s: ٪ d/n" ، this.getName () ، i) ؛ // عندما يمكن تقسيمها على 4 ، أنام لـ 100 مللي ثانية إذا (i ٪ 4 == 0) thread.sleep (100) ؛ }} catch (interruptedException e) {E.PrintStackTrace () ؛ }}} الفئة العامة sleeptest {public static void main (string [] args) {threada t1 = new threada ("t1") ؛ t1.start () ؛ }} نتائج التشغيل:
T1: 0T1: 1T1: 2T1: 3T1: 4T1: 5T1: 6T1: 7T1: 8T1: 9
وصف النتائج:
البرنامج بسيط نسبيًا ، بدء تشغيل THE T1 في مؤشر الترابط الرئيسي الرئيسي. بعد بدء تشغيل T1 ، عندما يمكن تقسيم الحساب I في T1 على 4 ، سينام T1 مقابل 100 ميلي ثانية من خلال Thread.sleep (100).
مقارنة بين النوم () وانتظر ():
نحن نعلم أن وظيفة WAIT () هي السماح للمعلومات الحالية بدخول حالة "الانتظار (حظر) من" حالة الجري "وأيضًا إطلاق قفل المزامنة. تتمثل وظيفة النوم () في السماح للموضوع الحالي بإدخال" حالة النوم (الحظر) "من" الحالة الجارية ".
ومع ذلك ، انتظر () يطلق قفل تزامن الكائن ، في حين أن Sleep () لا يطلق القفل.
يوضح المثال التالي أن Sleep () لن يطلق القفل.
الفئة العامة sleeplocktest {private static object obj = new Object () ؛ public static void main (string [] args) {threada t1 = new threada ("t1") ؛ threada t2 = new threada ("t2") ؛ t1.start () ؛ t2.start () ؛ } static class threada يمتد thread {public threada (اسم السلسلة) {super (name) ؛ } public void run () {// احصل على قفل المزامنة لكائن OBJ المتزامن (obj) {try {for (int i = 0 ؛ i <10 ؛ i ++) {system.out.printf ("٪ s: ٪ d/n" ، this.getName () ، i) ؛ // عندما يمكن تقسيمها على 4 ، أنام لـ 100 مللي ثانية إذا (i ٪ 4 == 0) thread.sleep (100) ؛ }} catch (interruptedException e) {E.PrintStackTrace () ؛ }}}}}}}}} نتائج التشغيل:
T1: 0T1: 1T1: 2T1: 3T1: 4T1: 5T1: 6T1: 7T1: 8T1: 9T2: 0T2: 1T2: 2T2: 3T2: 4T2: 5T2: 6T2: 7T2: 8T2: 9
وصف النتائج:
يتم تشغيل خيطين T1 و T2 في الخيط الرئيسي الرئيسي. سيشير T1 و T2 إلى قفل المزامنة لنفس الكائن في التشغيل () ، أي متزامن (OBJ). أثناء تشغيل T1 ، على الرغم من أنه سيتصل بالموضوع. sleep (100) ؛ لن تحصل T2 على حقوق تنفيذ وحدة المعالجة المركزية. لأن T1 لا يطلق "القفل المتزامن الذي يحتفظ به OBJ"!
لاحظ أنه إذا علقت المزامنة (OBJ) وتنفيذ البرنامج مرة أخرى ، يمكن تبديل T1 و T2 إلى بعضهما البعض. فيما يلي رمز المصدر بعد حن التعليق المتزامن (OBJ):
الفئة العامة sleeplocktest {private static object obj = new Object () ؛ public static void main (string [] args) {threada t1 = new threada ("t1") ؛ threada t2 = new threada ("t2") ؛ t1.start () ؛ t2.start () ؛ } static class threada يمتد thread {public threada (اسم السلسلة) {super (name) ؛ } public void run () {// احصل على قفل المزامنة لكائن OBJ // synchronized (obj) {try {for (int i = 0 ؛ i <10 ؛ i ++) {system.out.printf ("٪ s: ٪ d/n" ، this.getName () ، i) ؛ // عندما يمكن تقسيمها على 4 ، أنام لـ 100 مللي ثانية إذا (i ٪ 4 == 0) thread.sleep (100) ؛ }} catch (interruptedException e) {E.PrintStackTrace () ؛ } //}}}}