1. أثيرت مشكلة متزامنة
تزامن مؤشر الترابط هو منع تلف البيانات عند الوصول إلى كائن بيانات.
على سبيل المثال: يقوم كل من Threads Threada و Threadb بتشغيل كائن FOO نفسه وتعديل البيانات على كائن FOO.
Package Cn.Thread ؛ public class foo {private int x = 100 ؛ public int getx () {return x ؛ } public int fix (int y) {x = x - y ؛ إرجاع x ؛ }} Package Cn.Thread ؛ public class myrunnable تنفس {private foo foo = new foo () ؛ public static void main (string [] args) {myrunnable run = new myrunnable () ؛ THELL TA = موضوع جديد (تشغيل ، "Thread-A") ؛ Thind Tb = Thread New (Run ، "Thread-B") ؛ ta.start () ؛ tb.start () ؛ } public void run () {for (int i = 0 ؛ i <3 ؛ i ++) {this.fix (30) ؛ حاول {thread.sleep (1) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } system.out.println (thread.currentThRead (). getName () + ": القيمة x للكائن الحالي foo =" + foo.getx ()) ؛ }} public int fix (int y) {return foo.fix (y) ؛ }}نتائج التشغيل:
مؤشر الترابط: القيمة x لكائن FOO الحالي = 40
Thread-A: القيمة x لكائن FOO الحالي = 40
مؤشر الترابط: القيمة x لكائن FOO الحالي = -20
Thread -A: القيمة x لكائن FOO الحالي = -20
مؤشر الترابط ب: القيمة x لكائن FOO الحالي = -80
Thread -A: القيمة x لكائن FOO الحالي = -80
من النتائج ، وجد أن قيمة الإخراج هذه كانت غير معقولة بشكل واضح. والسبب هو أن اثنين من مؤشرات الترابط الوصول إلى كائنات FOO دون التحكم وتعديل بياناتهما.
إذا كنت ترغب في الحفاظ على عقلانية النتائج ، فأنت بحاجة فقط إلى تحقيق هدف واحد ، وهو تقييد الوصول إلى FOO ، ويمكن لخيط واحد فقط الوصول إليه في وقت واحد. هذا سيضمن عقلانية البيانات في كائن FOO.
في رمز Java المحدد ، يجب إكمال عمليتين:
حدد متغير FOO X لفئة الموارد التي تمت زيارتها من قبل المنافسة على أنها خاصة ؛
مزامنة الكود الذي يعدل المتغيرات ، واستخدم الكلمة الرئيسية المتزامنة لمزامنة الطريقة أو الكود.
Package Cn.Thread ؛ public class foo2 {private int x = 100 ؛ public int getx () {return x ؛ }. System.out.println ("thread" + thread.currentThRead (). getName () + "Run النهايات ، تقليل" " + y +" ، القيمة الحالية هي: " + x) ؛ إرجاع x ؛ } // // كتلة رمز متزامنة // public int fix (int y) {// synchronized (this) {// x = x - y ؛ // system.out.println ("thread" + thread.currentThread (). getName () + "Run النهايات ، تقليل" " + y // +" ، القيمة الحالية هي: " + x) ؛ //} // Package Cn.Thread ؛ public class myrunnable2 {public static void main (string [] args) {myrunnable2 run = new myrunnable2 () ؛ foo2 foo2 = new foo2 () ؛ mythread t1 = run.new mythread ("thread a" ، foo2 ، 10) ؛ mythread t2 = run.new mythread ("thread b" ، foo2 ، -2) ؛ mythread t3 = run.new mythread ("thread c" ، foo2 ، -3) ؛ mythread t4 = run.new mythread ("thread d" ، foo2 ، 5) ؛ t1.start () ؛ t2.start () ؛ t3.start () ؛ t4.start () ؛ } class myThread يمتد thread {private foo2 foo2 ؛ / ** القيمة الحالية*/ private int y = 0 ؛ myThread (اسم السلسلة ، foo2 foo2 ، int y) {super (name) ؛ this.foo2 = foo2 ؛ this.y = y ؛ } public void run () {foo2.fix (y) ؛ }}} الموضوع A -Run ينتهي ، يقلل من "10" ، القيمة الحالية هي: 90
يدير الموضوع C وينتهي ، يقلل "-3" ، القيمة الحالية هي: 93
يعمل الموضوع B في النهاية ، ويقلل "-2" ، والقيمة الحالية هي: 95
يدير الموضوع D وينتهي ، يقلل من "5" ، القيمة الحالية هي: 90
2. التزامن والقفل
1. مبدأ القفل
كل كائن في جافا لديه قفل مدمج.
عندما يعمل البرنامج على طريقة المزامنة غير المنتظمة ، فإن القفل المرتبط بالمثال الحالي لفئة الكود التي يتم تنفيذها (هذه الحالة). يُطلق على القفل الذي يكتسب كائنًا أيضًا الحصول على قفل أو قفل كائن أو قفل على كائن أو مزامنة على كائن.
يعمل قفل الكائن فقط عندما يتم تشغيل البرنامج إلى طريقة المزامنة المتزامنة أو كتلة التعليمات البرمجية.
لا يوجد سوى قفل واحد لكائن. لذلك ، إذا حصل مؤشر ترابط على القفل ، فلن يتمكن أي مؤشر ترابط آخر من الحصول على القفل حتى يطلق (أو إرجاع) القفل. هذا يعني أيضًا أنه لا يمكن لأي مؤشر ترابط آخر إدخال الطريقة أو كتلة رمز متزامنة على الكائن حتى يتم إصدار القفل.
إن إطلاق القفل يعني أن مؤشر ترابط القفل يخرج من طريقة المزامنة المتزامنة أو كتلة رمز.
هناك بعض النقاط الرئيسية حول القفل والمزامنة:
1) يمكن مزامنة الطرق فقط ، ولكن لا يمكن مزامنة المتغيرات والفئات ؛
2) كل كائن لديه قفل واحد فقط ؛ عندما يتعلق الأمر بالمزامنة ، ما الذي يجب أن يكون واضحًا؟ وهذا هو ، على أي كائن تزامن؟
3) ليست هناك حاجة لمزامنة جميع الطرق في الفصل. يمكن أن يكون لكل من الأساليب المتزامنة وغير المتزامنة.
4) إذا أراد ترابطان تنفيذ الطريقة المتزامنة في فئة واحدة ، واستخدم الخيطان نفس المثيل لاستدعاء الطريقة ، فيمكن أن يقوم مؤشر ترابط واحد فقط بتنفيذ الطريقة في وقت واحد ، ويحتاج الآخر إلى الانتظار حتى يتم إصدار القفل. هذا هو: إذا اكتسب مؤشر ترابط قفل على كائن ، فلا يمكن لأي مؤشر ترابط آخر إدخال أي طريقة تزامن في الفئة (من هذا الكائن).
5) إذا كان مؤشر الترابط يحتوي على تزامن وطرق غير متزامنة ، فيمكن الوصول إلى الطرق غير المتزامنة بحرية بواسطة مؤشرات ترابط متعددة دون تقييد الأقفال.
6) عندما ينام الخيط ، لن يتم إصدار أي قفل يحمله.
7) يمكن أن تحصل على قوائم متعددة الأقفال. على سبيل المثال ، فإن استدعاء طريقة التزامن لكائن آخر في طريقة التزامن لكائن واحد سيحصل على قفل المزامنة للكائنين.
8) التزامن يضعف التزامن ويجب أن يضيق نطاق التزامن قدر الإمكان. لا يمكن للمزامنة مزامنة الطريقة بأكملها فحسب ، بل تتم مزامنة بعض كتل التعليمات البرمجية في الطريقة.
9) عند استخدام كتل رمز التزامن ، يجب عليك تحديد الكائن الذي يجب مزامنته ، أي ، أي قفل الكائن يتم الحصول عليه. على سبيل المثال:
public int fix (int y) {synchronized (this) {x = x - y ؛ } إرجاع x ؛} بالطبع ، يمكن أيضًا إعادة كتابة طريقة التزامن كطريقة غير متزامنة ، لكن الوظائف متشابهة تمامًا ، على سبيل المثال:
المزامنة العامة int getx () {return x ++ ؛} و
public int getx () {synchronized (this) {return x ++ ؛ }}التأثير هو نفسه بالضبط.
3. تزامن الطريقة الثابتة
لمزامنة الطرق الثابتة ، هناك حاجة إلى قفل لكائن الفئة بأكمله ، وهو هذه الفئة (xxx.class).
على سبيل المثال:
STATIC STATIC STATIC SETNAME (اسم السلسلة) {xxx.name = name ؛}
أي ما يعادل
public static int setName (اسم السلسلة) {synchronized (xxx.class) {xxx.name = name ؛ }}4. ماذا يحدث إذا لم يتمكن الخيط من الحصول على القفل
إذا حاول مؤشر الترابط إدخال طريقة متزامنة وتم احتلال قفله ، فسيتم حظر الخيط على الكائن. في الأساس ، يدخل مؤشر الترابط مجموعة من الكائن ويجب أن ينتظر حيث يجب أن ينتظر حتى يتم إطلاق قفله ويصبح الخيط قابل للتشغيل أو يعمل مرة أخرى.
عند التفكير في الحجب ، تأكد من الانتباه إلى أي كائن يستخدم في القفل:
1. الخيوط التي تسمي طرق التزامن غير السترات في نفس الكائن سوف تمنع بعضها البعض. إذا كان كائنًا مختلفًا ، فإن كل مؤشر ترابط يحتوي على قفل كائن خاص به ، ولا تتداخل مؤشرات الترابط مع بعضها البعض.
2. الخيوط التي تستدعي طرق التزامن الثابت في نفس الفئة ستحظر بعضها البعض ، وكلها مغلقة على نفس كائن الفئة.
3. لن تمنع طرق التزامن الثابت وطرق التزامن غير القتالية بعضها البعض ، لأن الطرق الثابتة مقفلة على كائنات الفصل ، في حين أن الطرق غير المنطقية مقفلة على كائنات هذه الفئة.
4. بالنسبة لكتل التعليمات البرمجية المتزامنة ، تحتاج إلى معرفة بوضوح الكائنات التي تم استخدامها في القفل (محتويات الأقواس المتزامنة بعد المزامنة). ستمنع مؤشرات الترابط المزامنة على نفس الكائن بعضها البعض ، ولن تمنع مؤشرات الترابط المغلقة على كائنات مختلفة أبدًا بعضها البعض.
5. متى الحاجة إلى المزامنة
عند الوصول إلى بيانات متعددة من البيانات الحصرية (القابلة للتبادل) في وقت واحد ، يجب مزامنة لحماية البيانات ، مع التأكد من عدم تعديل كلا الموضوعين وتغييرها في نفس الوقت.
بالنسبة للبيانات التي يمكن تغييرها في الحقول غير المنتظمة ، عادة ما يتم الوصول إلى الطرق غير المنتظمة.
بالنسبة للبيانات التي يمكن تغييرها في حقل ثابت ، يتم الوصول إليه عادةً باستخدام طريقة ثابتة.
تصبح المشكلة معقدة للغاية إذا كنت بحاجة إلى استخدام حقول ثابتة في الأساليب غير الستاطية ، أو استدعاء الطرق غير المنتظمة في الحقول الثابتة. لقد تجاوز نطاق امتحان SJCP.
6. فئة سلامة الموضوع
عندما تتم مزامنة الفصل بشكل جيد لحماية بياناتها ، تسمى هذه الفئة "آمنة مؤشرات الترابط".
حتى بالنسبة لفئات آمنة الخيط ، يجب أن تكون حذراً للغاية ، لأن الخيوط التي تعمل لا تزال غير آمنة بالضرورة.
7. ملخص مزامنة الموضوع
1. الغرض من مزامنة الخيط هو حماية الأضرار التي لحقت بالموارد عندما تصل مؤشرات الترابط المتعددة إلى مورد.
2. يتم تنفيذ طريقة مزامنة الخيط من خلال الأقفال. كل كائن لديه قفل واحد فقط. يرتبط هذا القفل بكائن معين. بمجرد أن يحصل مؤشر الترابط على قفل الكائن ، لم يعد بإمكان مؤشرات الترابط الأخرى الوصول إلى الكائن الوصول إلى طرق التزامن الأخرى للكائن.
3. بالنسبة لطرق التزامن الثابت ، تكون الأقفال لهذه الفئة ، وكائنات قفل هي كائنات فئة من هذه الفئة. لا تتداخل أقفال الأساليب الثابتة وغير الستاصلة مع بعضها البعض. يكتسب مؤشر الترابط قفلًا ، وعند الوصول إلى طريقة التزامن على كائن آخر في طريقة التزامن ، فإنه يكتسب هذين الأقفال الكائن.
4. للمزامنة ، من المفتاح دائمًا أن تكون على دراية بالكائن الذي يجب مزامنته.
5. عند كتابة فصول آمنة من مؤشرات الترابط ، تحتاج إلى الانتباه دائمًا إلى إصدار أحكام صحيحة حول منطق وأمان مؤشرات ترابط متعددة تتنافس على الوصول إلى الموارد ، وتحليل العمليات "الذرية" ، والتأكد من أنه لا يمكن للموارد الأخرى الوصول إلى الموارد المتنافسة أثناء العملية الذرية.
6. عندما تنتظر مؤشرات الترابط المتعددة قفل كائن ، سيتم حظر مؤشر الترابط الذي لم يحصل على القفل.
7. تسبب Deadlock في خيوط تنتظر قفل بعضها البعض ، واحتمال حدوثها في الواقع صغير جدًا. إذا كنت ترغب حقًا في كتابة برنامج Deadlock ، فقد لا يكون من السهل استخدامه ، هاها. ومع ذلك ، بمجرد وفاة البرنامج ، سيموت البرنامج.
الرابط الأصلي: http://www.cnblogs.com/linjiqin/p/3208843.html
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.