تشارك المقالة 4 أمثلة من شرح مفصل للمزامنة
1. ما إذا كنت ستضيف الكلمات الرئيسية المتزامنة
الفئة العامة threadtestest {public static void main (string [] args) {example example = new example () ؛ الموضوع T1 = Thread1 جديد (مثال) ؛ الموضوع T2 = new thread1 (مثال) ؛ t1.start () ؛ t2.start () ؛ }} class example {public synchronized void justar () {for (int i = 0 ؛ i <5 ؛ ++ i) {try {thread.sleep (1000) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } system.out.println ("excute:" + i) ؛ }}} class thread1 يمتد مؤشر الترابط {مثال خاص ؛ public thread1 (مثال على سبيل المثال) {this.example = example ؛ } Override public void run () {example.excute () ؛ }}النتيجة الإخراج للكلمة الرئيسية المتزامنة هي كما يلي
سيتم إخراج مجموعة من 0-4 أولاً ، ثم سيتم إخراج المجموعة التالية ، وسيتم تنفيذ الخيوط بالتسلسل.
Excute: 0
Excute: 1
Excute: 2
Excute: 3
Excute: 4
Excute: 0
Excute: 1
Excute: 2
Excute: 3
Excute: 4
النتيجة الإخراج للكلمة الرئيسية المتزامنة هي كما يلي
يقوم اثنين من المواضيع بتنفيذ طريقة excute في وقت واحد وبشكل متزامن
Excute: 0
Excute: 0
Excute: 1
Excute: 1
Excute: 2
Excute: 2
Excute: 3
Excute: 3
Excute: 4
Excute: 4
2. الوضع متعدد الخيوط لطرق متعددة
الفئة العامة threadtestest {public static void main (string [] args) {example example = new example () ؛ الموضوع T1 = Thread1 جديد (مثال) ؛ الموضوع T2 = Thread2 جديد (مثال) ؛ t1.start () ؛ t2.start () ؛ }} class example {public synchronized void justar () {for (int i = 0 ؛ i <5 ؛ ++ i) {try {thread.sleep (1000) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } system.out.println ("excute:" + i) ؛ }} public synchronized void direcl1 () {for (int i = 0 ؛ i <5 ؛ ++ i) {try {thread.sleep (1000) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } system.out.println ("excute1:" + i) ؛ }}} class thread1 يمتد مؤشر الترابط {مثال خاص ؛ public thread1 (مثال على سبيل المثال) {this.example = example ؛ } Override public void run () {example.excute () ؛ }} class thread2 يمتد مؤشر الترابط {مثال خاص ؛ public thread2 (مثال مثال) {this.example = example ؛ } Override public void run () {example.excute1 () ؛ }}نتائج التنفيذ هي كما يلي
يتم تنفيذ الشيء نفسه بالتسلسل ، ويتم تنفيذ مؤشر ترابط واحد قبل تنفيذ مؤشر ترابط آخر.
Excute: 0
Excute: 1
Excute: 2
Excute: 3
Excute: 4
Excute1: 0
Excute1: 1
Excute1: 2
Excute1: 3
حصري 1: 4
إذا تمت إزالة الكلمة الرئيسية المتزامنة ، فسيتم تنفيذ الطريقتين بشكل متزامن وليس لهما تأثير متبادل.
ولكن كما هو مكتوب في المثال الفرعي ، حتى طريقتين:
نتيجة التنفيذ هي دائمًا إخراج مؤشر ترابط واحد ثم تنفيذ مؤشر ترابط آخر.
يوضح:
إذا كان للكائن طرقًا متعددة متزامنة ، وأدخل مؤشر ترابط طريقة متزامنة في لحظة معينة ، فلن تتمكن مؤشرات الترابط الأخرى من الوصول إلى أي طرق متزامنة للكائن قبل تنفيذ الطريقة.
ختاماً:
عندما تعدل الكلمة الرئيسية المتزامنة طريقة ، تسمى الطريقة طريقة التزامن.
كل كائن في جافا لديه قفل ، أو شاشة. عندما يصل مؤشر ترابط إلى الطريقة المتزامنة لكائن ما ، يتم قفل الكائن ، ولا يمكن لأي مؤشر ترابط آخر الوصول إلى الطريقة المتزامنة للكائن (هنا يشير إلى جميع طرق المزامنة ، وليس فقط الطريقة نفسها). لن يتم ذلك حتى يكمل مؤشر الترابط السابق طريقة التنفيذ (أو يلقي استثناءً) ، حيث يتم إصدار قفل الكائن ، بحيث يمكن لخيوط أخرى الوصول إلى الطريقة المتزامنة للكائن مرة أخرى.
لاحظ أن الكائن مغلق في هذا الوقت. إذا كان كائنًا مختلفًا ، فلا توجد علاقة قيود بين الكائنات.
عند محاولة إنشاء كائن مؤشر ترابط ثانٍ في الكود ، يتم تمرير كائن مثال جديد ، ثم لا يوجد أي قيود بين تنفيذ المواضيع.
3. طريقة التزامن الثابت
عندما يتم تعديل طريقة تعديل الكلمة الرئيسية المتزامنة أيضًا بواسطة ثابت ، فقد قيل من قبل أن طريقة المزامنة غير الستائية ستقفل الكائن ، لكن الطريقة الثابتة لا تنتمي إلى الكائن ، بل فئة ، وستغلق كائن الفئة من الفئة حيث توجد هذه الطريقة.
الفئة العامة threadtestest {public static void main (string [] args) {example example = new example () ؛ مثال 2 = مثال جديد () ؛ الموضوع T1 = Thread1 جديد (مثال) ؛ الموضوع T2 = new thread2 (example2) ؛ t1.start () ؛ t2.start () ؛ }} example {public synchronized static void justar () {for (int i = 0 ؛ i <5 ؛ ++ i) {try {thread.sleep (1000) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } system.out.println ("excute:" + i) ؛ }}} متزامن عام static void require1 () {for (int i = 0 ؛ i <5 ؛ ++ i) {try {thread.sleep (1000) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } system.out.println ("excute1:" + i) ؛ }}} class thread1 يمتد مؤشر الترابط {مثال خاص ؛ public thread1 (مثال على سبيل المثال) {this.example = example ؛ } Override public void run () {example.excute () ؛ }} class thread2 يمتد مؤشر الترابط {مثال خاص ؛ public thread2 (مثال مثال) {this.example = example ؛ } Override public void run () {example.excute1 () ؛ }}نتائج التنفيذ هي كما يلي
Excute: 0
Excute: 1
Excute: 2
Excute: 3
Excute: 4
Excute1: 0
Excute1: 1
Excute1: 2
Excute1: 3
حصري 1: 4
إذا لم يكن هناك معدّل ثابت ، ويمرر ترابطان كائنات مختلفة ، فسيتم تنفيذهما بشكل متزامن في نفس الوقت.
لذلك إذا كانت طريقة ثابتة (تنفيذ () وتنفيذ 2 () ، تمت إضافة كلمات رئيسية ثابتة) ، حتى لو تم تمرير كائنات مثال مختلفة إلى مؤشر ترابط ، لا يزال هناك مؤشر ترابط مقيدين من قبل بعضهما البعض. يجب تنفيذ المرء أولاً ثم واحد التالي.
ختاماً:
إذا كانت طريقة متزامنة ثابتة ، عندما يصل مؤشر ترابط إلى الطريقة ، فإنه لا يغلق الكائن الذي توجد فيه الطريقة المتزامنة ، ولكن كائن الفئة المقابل للفئة حيث توجد الطريقة المتزامنة. في Java ، بغض النظر عن عدد الكائنات التي لدى الفئة ، ستتوافق هذه الكائنات مع كائن فئة فريد. لذلك ، عندما يصل مؤشر ترابط إلى طريقتين ثابتتين ومتوازنة لكائنين من نفس الفئة ، يكون ترتيب التنفيذ الخاص بهما متسلسلًا أيضًا ، أي أن سلسلة رسائل واحدة تنفذ الطريقة أولاً ، ويبدأ مؤشر الترابط الآخر بعد اكتمال التنفيذ.
4. كتلة متزامنة
متزامن (كائن)
{
}
وهذا يعني أن مؤشر الترابط سيغلق كائن الكائن عند تنفيذه. (لاحظ أن هذا الكائن يمكن أن يكون كائنًا لأي فئة ، أو يمكنك استخدام هذه الكلمة الرئيسية).
بهذه الطريقة ، يمكنك تحديد الكائن المقفل بنفسك.
الفئة العامة threadtestest {public static void main (string [] args) {example example = new example () ؛ الموضوع T1 = Thread1 جديد (مثال) ؛ الموضوع T2 = Thread2 جديد (مثال) ؛ t1.start () ؛ t2.start () ؛ }} class example {public void juduct () {synchronized (this) {for (int i = 0 ؛ i <5 ؛ ++ i) {try {thread.sleep (1000) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } system.out.println ("excute:" + i) ؛ }}} public void justire1 () {synchronized (this) {for (int i = 0 ؛ i <5 ؛ ++ i) {try {thread.sleep (1000) ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } system.out.println ("excute1:" + i) ؛ }}}}}} Class Thread1 يمتد Thread {مثال خاص على مثال ؛ public thread1 (مثال على سبيل المثال) {this.example = example ؛ } Override public void run () {example.excute () ؛ }} class thread2 يمتد مؤشر الترابط {مثال خاص ؛ public thread2 (مثال مثال) {this.example = example ؛ } Override public void run () {example.excute1 () ؛ }}نتائج التنفيذ هي كما يلي
Excute: 0
Excute: 1
Excute: 2
Excute: 3
Excute: 4
Excute1: 0
Excute1: 1
Excute1: 2
Excute1: 3
حصري 1: 4
التأثير الذي تم تحقيقه عن طريق البرنامج 4 هو نفس برنامج المثال 2. يتم تنفيذ كلا الموضوعين بالتسلسل ، وليس بشكل متزامن. عندما يتم تنفيذ مؤشر ترابط واحد ، يتم قفل كائن الكائن ، ولا يمكن للمعلومات الأخرى تنفيذ الكتلة المقابلة.
الطريقة المتزامنة تعادل في الواقع لف جميع العبارات في الطريقة باستخدام كتلة متزامنة ، ثم تمرير هذه الكلمة الرئيسية في قوسين الكتلة المتزامنة. بالطبع ، إذا كانت طريقة ثابتة ، فيجب قفل كائن الفصل.
ربما ستشمل بضعة أسطر من التعليمات البرمجية في طريقة ما مشكلات مزامنة مؤشر الترابط ، وبالتالي فإن الكتلة المتزامنة تتحكم في الوصول إلى مؤشرات ترابط متعددة أكثر من الطريقة المتزامنة. لا يمكن الوصول إلى المحتوى في الكتلة المتزامنة فقط بواسطة مؤشرات ترابط متعددة في نفس الوقت ، ولا يزال من الممكن الوصول إلى عبارات أخرى في الطريقة بواسطة مؤشرات ترابط متعددة في نفس الوقت (بما في ذلك قبل وبعد الكتلة المتزامنة).
ختاماً:
الطريقة المتزامنة هي تحكم متزامن الحبيبات الخشنة. في لحظة معينة ، يمكن لخيط واحد فقط تنفيذ الطريقة المتزامنة ؛
الكتلة المتزامنة هي عنصر تحكم في التزامن دقيق ، والذي يزامن فقط الرمز في الكتلة. يمكن الوصول إلى الرموز الأخرى الموجودة في الطريقة وبخلاف الكتل المتزامنة بواسطة مؤشرات ترابط متعددة في نفس الوقت.
ما سبق حول طريقة مزامنة الكتلة المتزامنة للبرمجة متعددة الخيوط Java. آمل أن يكون ذلك مفيدًا لتعلم الجميع.