سؤال

لدي بعض الأسئلة بخصوص استخدام وأهمية synchronized الكلمة الرئيسية.

  • ما هي أهمية synchronized الكلمة الرئيسية؟
  • متى يجب أن تكون الأساليب synchronized?
  • ماذا يعني برمجيا ومنطقيا؟
هل كانت مفيدة؟

المحلول

ال synchronized الكلمة الرئيسية هي كل شيء عن مؤشرات الترددات المختلفة والكتابة إلى نفس المتغيرات والكائنات والموارد. هذا ليس موضوع تافه في جافا، ولكن هنا هو اقتباس من الشمس:

synchronized تتيح الطرق استراتيجية بسيطة لمنع تداخل مؤشر الترابط وأخطاء تناسق الذاكرة: إذا كان كائن مرئي لأكثر من مؤشر ترابط واحد، تتم جميع القراءات أو يكتب إلى متغيرات هذا الكائن من خلال الطرق المتزامنة.

باختصار صغير جدا جدا: عندما يكون لديك اثنين من الخيوط التي تقرأ والكتابة إلى نفس الموارد "، قل متغير اسمه foo, ، تحتاج إلى ضمان الوصول إلى هذه المواضيع المتغير بطريقة ذرية. بدون ال synchronized الكلمة الرئيسية، الموضوع الخاص بك 1 قد لا يرى تغيير موضوع التغيير 2 foo, أو أسوأ الأمر، قد يكون فقط نصف تغيرت. هذا لن يكون ما تتوقعه منطقيا.

مرة أخرى، هذا موضوع غير تافهة في جافا. لمعرفة المزيد، استكشف الموضوعات هنا على ذلك و Interwebs حول:

استمر في استكشاف هذه الموضوعات حتى الاسم "براين جوتز" يصبح مرتبطا بشكل دائم بالمصطلح "التزامن" في عقلك.

نصائح أخرى

حسنا، أعتقد أن لدينا ما يكفي من التفسيرات النظرية، لذلك النظر في هذا الرمز

public class SOP {
    public static void print(String s) {
        System.out.println(s+"\n");
    }
}

public class TestThread extends Thread {
    String name;
    TheDemo theDemo;
    public TestThread(String name,TheDemo theDemo) {
        this.theDemo = theDemo;
        this.name = name;
        start();
    }
    @Override
    public void run() {
        theDemo.test(name);
    }
}

public class TheDemo {
    public synchronized void test(String name) {
        for(int i=0;i<10;i++) {
            SOP.print(name + " :: "+i);
            try{
                Thread.sleep(500);
            } catch (Exception e) {
                SOP.print(e.getMessage());
            }
        }
    }
    public static void main(String[] args) {
        TheDemo theDemo = new TheDemo();
        new TestThread("THREAD 1",theDemo);
        new TestThread("THREAD 2",theDemo);
        new TestThread("THREAD 3",theDemo);
    }
}

ملحوظة: synchronized كتل مكالمة الخيط التالي للاختبار الطريقة () طالما لم يتم الانتهاء من تنفيذ الخيط السابق. الخيوط يمكن الوصول إلى هذه الطريقة واحدة في وقت واحد. بدون synchronized جميع المواضيع يمكن الوصول إلى هذه الطريقة في وقت واحد.

عندما يستدعي الخيط طريقة "اختبار" الطريقة المتزامنة للكائن (الكائن هنا هو مثيل من فئة "Thedemo")، فإنه يكتسب قفل هذا الكائن، أي مؤشر ترابط جديد لا يمكنه الاتصال بأي طريقة متزامنة لنفس الكائن طالما الموضوع السابق التي اكتسبت القفل لا يطلق القفل.

يحدث شيء مماثل عند استدعاء أي طريقة متزامنة ثابتة للفئة. يكتسب الخيط القفل المرتبط بالفصل (في هذه الحالة، يمكن استدعاء أي طريقة غير متزامنة غير ثابتة مثيل من تلك الفئة بواسطة أي ترابط لأن قفل مستوى الكائن لا يزال متاحا). لن يتمكن أي مؤشر ترابط آخر من الاتصال بأي طريقة متزامنة ثابتة للفئة طالما لم يتم إصدار قفل مستوى الفصل بواسطة مؤشر الترابط الذي يحمل حاليا القفل.

الإخراج مع مزامنة

THREAD 1 :: 0
THREAD 1 :: 1
THREAD 1 :: 2
THREAD 1 :: 3
THREAD 1 :: 4
THREAD 1 :: 5
THREAD 1 :: 6
THREAD 1 :: 7
THREAD 1 :: 8
THREAD 1 :: 9
THREAD 3 :: 0
THREAD 3 :: 1
THREAD 3 :: 2
THREAD 3 :: 3
THREAD 3 :: 4
THREAD 3 :: 5
THREAD 3 :: 6
THREAD 3 :: 7
THREAD 3 :: 8
THREAD 3 :: 9
THREAD 2 :: 0
THREAD 2 :: 1
THREAD 2 :: 2
THREAD 2 :: 3
THREAD 2 :: 4
THREAD 2 :: 5
THREAD 2 :: 6
THREAD 2 :: 7
THREAD 2 :: 8
THREAD 2 :: 9

الإخراج دون مزامنة

THREAD 1 :: 0
THREAD 2 :: 0
THREAD 3 :: 0
THREAD 1 :: 1
THREAD 2 :: 1
THREAD 3 :: 1
THREAD 1 :: 2
THREAD 2 :: 2
THREAD 3 :: 2
THREAD 1 :: 3
THREAD 2 :: 3
THREAD 3 :: 3
THREAD 1 :: 4
THREAD 2 :: 4
THREAD 3 :: 4
THREAD 1 :: 5
THREAD 2 :: 5
THREAD 3 :: 5
THREAD 1 :: 6
THREAD 2 :: 6
THREAD 3 :: 6
THREAD 1 :: 7
THREAD 2 :: 7
THREAD 3 :: 7
THREAD 1 :: 8
THREAD 2 :: 8
THREAD 3 :: 8
THREAD 1 :: 9
THREAD 2 :: 9
THREAD 3 :: 9

ال synchronized تمنع الكلمة الرئيسية الوصول المتزامن إلى كتلة من التعليمات البرمجية أو الكائن حسب مؤشرات الترابط متعددة. بشكل افتراضي، Hashtable يكون synchronized, ، لذلك يمكن فقط موضوع واحد الوصول إلى الجدول في وقت واحد.

على استخدام non-synchronized بنيات مثل HashMap، يجب عليك بناء ميزات السلامة الخيط في التعليمات البرمجية لمنع أخطاء اتساق الذاكرة.

synchronized يعني أنه في بيئة متعددة الخيوط، وجود كائن synchronized طريقة (أساليب) / كتلة (ق) لا تدع مؤشر ترابطين للوصول إلى synchronized طريقة (أسلوب) / كتلة (ق) من التعليمات البرمجية في نفس الوقت. هذا يعني أن موضوع واحد لا يمكن أن يقرأ بينما يقوم مؤشر ترابط آخر بتحديثه.

سوف تنتظر الخيط الثاني بدلا من ذلك حتى يكمل مؤشر الترابط الأول تنفيذها. النفقات العامة هي السرعة، ولكن الميزة مضمونة باتساق البيانات.

إذا كان التطبيق الخاص بك هو واحد الخيوط، synchronized الكتل لا توفر الفوائد.

ال synchronized تسبب الكلمة الأساسية مؤشر ترابط للحصول على قفل عند إدخال الطريقة، بحيث يمكن لخيط واحد فقط تنفيذ الطريقة في نفس الوقت (مثيل الكائنات المعينة، ما لم تكن طريقة ثابتة).

كثيرا ما يسمى هذا جعل خيط الصفحات الفئة آمنة، لكنني سأقول أن هذه هي إرهائية. في حين أنه صحيح أن المزامنة يحمي الحالة الداخلية للمتجه من الزفال، إلا أن هذا لا يساعد عادة مستخدم متجه كثيرا.

النظر في هذا:

 if (vector.isEmpty()){
     vector.add(data);
 }

على الرغم من أن الطرق المعنية متزامنة، لأنها يتم تأمينها وإلغاء تأمينها بشكل فردي، فإن اثنين من المواضيع المتوقفة للأسف يمكن أن تخلق متجه مع عنصرين.

لذلك ساري المفعول، يجب عليك مزامنة في رمز التطبيق الخاص بك أيضا.

نظرا لأن المزامنة على مستوى الطريقة هي أ) باهظة الثمن عندما لا تحتاج إليها و B) غير كافية عندما تحتاج إلى مزامنة، فهناك الآن بدائل غير متزامنة (صفيف القائمة في حالة ناقل).

في الآونة الأخيرة، تم إصدار حزمة التزامن، مع عدد من الأدوات المساعدة الذكية التي تعتني بقضايا متعددة الخيوط.

ملخص

الكلمة الرئيسية المتزامنة في Java يجب أن تفعل مع سلامة الخيط، وهذا هو، عند قراءة مؤشرات الترابط متعددة أو كتابة نفس المتغير.
يمكن أن يحدث هذا مباشرة (عن طريق الوصول إلى نفس المتغير) أو غير مباشر (باستخدام فئة تستخدم فئة أخرى تصل إلى نفس المتغير).

يتم استخدام الكلمة الأساسية المتزامنة لتحديد كتلة من التعليمات البرمجية حيث يمكن أن تصل مواضيع متعددة إلى نفس المتغير بطريقة آمنة.

أعمق

بناء الجملة الحكيم synchronized الكلمة الرئيسية تأخذ Object كما هي المعلمة (تسمى كائن قفل)، والذي يتبع بعد { block of code }.

  • عند مواجهة التنفيذ هذه الكلمة الأساسية، يحاول الخيط الحالي "قفل / الحصول على / الخاصة" (خذ اختيارك) قفل كائن وتنفيذ كتلة التعليمات المرتبطة بعد الحصول على القفل.

  • يتم ضمان أي يكتب للمتغيرات داخل كتلة التعليمات البرمجية المتزامنة مرئية ليكون مرئيا لكل مؤشر ترابط آخر يزيد فيه تنفيذ التعليمات البرمجية داخل كتلة رمز متزامنة باستخدام نفسه قفل كائن.

  • يمكن أن يحمل مؤشر ترابط واحد فقط في وقت واحد القفل، خلالها كل المواضيع الأخرى التي تحاول اكتسابها قفل كائن سوف ننتظر (وقفة تنفيذها). سيتم إصدار القفل عند خروج التنفيذ كتلة التعليمات البرمجية المتزامنة.

الأساليب المتزامنة:

إضافة synchronized الكلمة الرئيسية لتعريف الطريقة تساوي هيئة الطريقة بأكملها ملفوفة في كتلة رمز متزامنة مع قفل كائن مستخدم this (على سبيل المثال طرق) و ClassInQuestion.getClass() (طرق الفصل).

- طريقة المثال هي طريقة لا تملك static الكلمة الرئيسية.
- طريقة الطبقة هي طريقة لها static الكلمة الرئيسية.

اصطلاحي

بدون مزامنة، لا يتم ضمان الطلب الذي يحدث فيه القراءات والكتابة، وربما ترك المتغير مع القمامة.
(على سبيل المثال، يمكن أن ينتهي المتغير بنصف البتات الذي كتبه مؤشر ترابط واحد ونصف بت مكتوب بواسطة مؤشر ترابط آخر، وترك المتغير في حالة لم يحاول أي من المواضيع الكتابة، ولكن فوضى مجتمعة من الاثنين.)

لا يكفي لإكمال عملية الكتابة في مؤشر ترابط قبل (وقت ساعة الحائط) يقرأه مؤشر ترابط آخر، لأن الأجهزة قد تم تخزينها مخزئة بقيمة المتغير، وسوف يرى مؤشر ترابط القراءة القيمة المخزنة مؤقتا بدلا من ما كتب إليه هو - هي.

خاتمة

وبالتالي في حالة Java، عليك اتباع نموذج ذاكرة Java لضمان عدم حدوث أخطاء الخيوط.
بمعنى آخر: استخدم المزامنة أو العمليات الذرية أو الفئات التي تستخدمها لك تحت الأغطية.

مصادر

http://docs.oracle.com/javase/specs/jls/se8/html/index.html.
مواصفات لغة Java®، 2015-02-13

فكر في الأمر كنوع من الباب الدوار مثلك قد تجد في أرض كرة قدم. هناك مشبخ متوازي من الأشخاص الذين يرغبون في الدخول ولكن في Troublistile "متزامنون". شخص واحد فقط في وقت يمكن الوصول إليه. كل هؤلاء الذين يرغبون في الوصول إليه سيفعلون، لكن قد يتعين عليهم الانتظار حتى يتمكنوا من المرور.

ما هي الكلمة الرئيسية المتزامنة؟

المواضيع التواصل بشكل أساسي عن طريق مشاركة الوصول إلى الحقول والحقول المرجعية كائنات تشير إلى. هذا الشكل من الاتصالات فعالة للغاية، ولكنه يجعل نوعين من الأخطاء ممكنة: تداخل مؤشر الترابط وأخطاء اتساق الذاكرة. وبعد الأداة اللازمة لمنع هذه الأخطاء هي المزامنة.

الكتل أو الأساليب المتزامنة يمنع تدخل الخيط وتأكد من أن البيانات متسقة. في أي وقت من الوقت، يمكن لخيط واحد فقط الوصول إلى كتلة أو طريقة متزامنة (جزء حرج) عن طريق الحصول على قفل. مؤشر ترابط آخر سوف ينتظر الإفراج عن قفل للوصول جزء حرج.

متى يتم مزامنة الأساليب؟

يتم مزامنة الأساليب عند إضافة synchronized لطريقة تعريف أو إعلان. يمكنك أيضا مزامنة كتلة معينة من التعليمات البرمجية مع-في الأسلوب.

ماذا يعني الموالية بشكل منطقي أو منطقيا؟

وهذا يعني أن موضوع واحد فقط يمكن الوصول إليه جزء حرج عن طريق الحصول على قفل. ما لم يكن هذا الخيط إصدار هذا القفل، سيتعين على جميع مؤشر الترابطات الأخرى الانتظار للحصول على قفل. ليس لديهم إمكانية الوصول إلى الدخول جزء حرج مع خارج الحصول على قفل.

هذا لا يمكن القيام به بسحر. إنها مسؤولية مبرمجة لتحديد القسم (القسم) الحرج في التطبيق وحراسة ذلك وفقا لذلك. يوفر Java إطارا لحراسة طلبك، ولكن أين وماذا يتم حراسة جميع الأقسام هو مسؤولية مبرمجة.

مزيد من التفاصيل من وثائق جافا صفحة

الأقفال الجوهرية والمزامنة:

تم تصميم التزامن حول كيان داخلي يعرف باسم قفل أو قفل الشاشة الجوهري. يلعب الأقفال الجوهرية دورا في جوانب المزامنة: إنفاذ الوصول الحصري إلى حالة الكائن وإنشاء يحدث - قبل العلاقات الضرورية للرؤية.

كل كائن لديه قفل جوهري مرتبط به. وبعد من خلال الاتفاقية، يتعين على مؤتمر الترابط الذي يحتاج إلى وصول حصري ومتسق إلى حقول الكائنات إلى قفل الكائن الخارجي قبل الوصول إليه، ثم حرر القفل الجوهري عند الانتهاء منه.

يقال إن مؤشر الترابط يمتلك القفل الجوهري بين الوقت الذي اكتسبته القفل وأصدر القفل. طالما تمتلك مؤشر ترابط قفل جوهري، لا يمكن لأي ترابط آخر الحصول على نفس القفل. سوف يمنع الخيط الآخر عندما يحاول الحصول على القفل.

عندما يطلق مؤشر ترابط قفل جوهري، يتم إنشاء العلاقة قبل ذلك بين هذا الإجراء وأي استحواذ لاحق لنفس القفل.

جعل طرق متزامنة لديها اثنين تأثيرات:

أولا، لا يمكن إجراء دعوتين من الأساليب المتزامنة على نفس الكائن إلى Interleave.

عندما يقوم مؤشر ترابط واحد بتنفيذ طريقة متزامنة للكائن، فإن جميع المواضيع الأخرى التي تستدعي الأساليب المتزامنة لنفس كتلة الكائنات (تعليق التنفيذ) حتى يتم تحديد مؤشر ترابط أول مع الكائن.

ثانيا، عند خروج الأسلوب المتزامن، فإنه يقوم تلقائيا بتأسيس علاقة قبل أي استدعاء لاحق لطريقة متزامنة لنفس الكائن.

هذه الضمانات التي تتغير في حالة الكائن مرئية لجميع المواضيع.

ابحث عن بدائل أخرى للمزامنة في:

تجنب مزامنة (هذا) في جافا؟

هنا شرح من دروس جافا.

النظر في التعليمات البرمجية التالية:

public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}

إذا count هو مثال من SynchronizedCounter, ، ثم جعل هذه الأساليب متزامنة لها تأثيران:

  • أولا، لا يمكن إجراء دعوتين من الأساليب المتزامنة على نفس الكائن إلى Interleave. عندما يقوم مؤشر ترابط واحد بتنفيذ طريقة متزامنة للكائن، فإن جميع المواضيع الأخرى التي تستدعي الأساليب المتزامنة لنفس كتلة الكائنات (تعليق التنفيذ) حتى يتم تحديد مؤشر ترابط أول مع الكائن.
  • ثانيا، عند خروج الأسلوب المتزامن، فإنه يقوم تلقائيا بتأسيس علاقة قبل أي استدعاء لاحق لطريقة متزامنة لنفس الكائن. هذه الضمانات التي تتغير في حالة الكائن مرئية لجميع المواضيع.

Synchronized normal method أي ما يعادلSynchronized statement (استخدم هذا)

class A {
    public synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(this) {
             // all function code
        }
    } 
}

Synchronized static method أي ما يعادل Synchronized statement (استخدم الفئة)

class A {
    public static synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(A.class) {
             // all function code
        }
    } 
}

بيان متزامن (باستخدام المتغير)

class A {
    private Object lock1 = new Object();

    public void methodA() {
        synchronized(lock1 ) {
             // all function code
        }
    } 
}

بالنسبة synchronized, ، لدينا كلا Synchronized Methods و Synchronized Statements. وبعد ومع ذلك، Synchronized Methods مشابه ل Synchronized Statements لذلك نحن فقط بحاجة إلى فهم Synchronized Statements.

=> أساسا، سيكون لدينا

synchronized(object or class) { // object/class use to provides the intrinsic lock
   // code 
}

هنا هو 2 أعتقد أن مساعدة فهم synchronized

  • كل كائن / فئة لديها intrinsic lock المرتبطة بها.
  • عندما يستدعي موضوع synchronized statement, ، يكتسب تلقائيا intrinsic lock من أجل هذا synchronized statement's كائن ويطلقه عند إرجاع الطريقة. طالما كان الموضوع يملك intrinsic lock, لا غير ذلك الموضوع يمكن الحصول على نفس قفل => خيط آمن.

=> عندما thread A يستدعي synchronized(this){// code 1} => كل رمز كتلة (داخل الفئة) حيث يكون synchronized(this) وكل synchronized normal method (داخل الطبقة) مغلقة بسبب نفس قفل. سوف تنفذ بعد thread A فتح ("// رمز 1" الانتهاء).

هذا السلوك يشبه synchronized(a variable){// code 1} أو synchronized(class).

نفس القفل => قفل (لا يعتمد على الطريقة التي؟ أو أي عبارات؟)

استخدام الطريقة المتزامنة أو البيانات المتزامنة؟

أنا أفضل synchronized statements لأنه أكثر قابل للتمديد. مثال، في المستقبل، تحتاج فقط إلى مزامنة جزء من الأسلوب. مثال، لديك طريقة متزامنة 2 ليس لديك أي ذات الصلة ببعضها البعض، ولكن عند تشغيل مؤشر ترابط أسلوب، سيتم حظر الطريقة الأخرى (يمكن أن تمنع عن طريق الاستخدام synchronized(a variable)).

ومع ذلك، تطبيق الطريقة المتزامنة بسيطة والرمز تبدو بسيطة. بالنسبة لبعض الفئة، هناك طريقة واحدة متزامنة فقط، أو جميع الأساليب المتزامنة في الفصل في ذات الصلة مع بعضنا البعض => يمكننا استخدامها synchronized method لجعل الرمز أقصر وسهلة الفهم

ملحوظة

(لا يرتبط الكثير ل synchronized, ، هو الاختلاف بين الكائن والطبقة أو لا شيء ثابت وثابت).

  • عند استخدامها synchronized أو الطريقة العادية أو synchronized(this) أو synchronized(non-static variable) سوف تتم مزامنة قاعدة على كل مثيل كائن.
  • عند استخدامها synchronized أو طريقة ثابتة أو synchronized(class) أو synchronized(static variable) وسوف تتم مزامنة قاعدة على الفئة

مرجع

https:/docs.oracle.com/javase/tutorial/essental/concurrency/syncmeth.html. https://docs.oracle.com/javase/tutorial/essental/concurrency/locksync.html.

آمل أن يساعد ذلك

إلى أفهمي متزامنة يعني بشكل أساسي أن التحويل البرمجي يكتب مراقبا. enter and monitor.exit حول طريقتك. على هذا النحو، قد يكون من الخيط آمنا اعتمادا على كيفية استخدامه (ما أقصده هو كتابة كائن مع الأساليب المتزامنة التي ليست مؤلفة اعتمادا على ما يفعله صفك).

ما تفتقده الإجابات الأخرى هو جانب مهم: حواجز الذاكرة.تتكون مزامنة الخيط بشكل أساسي من اثنين القطع:التسلسل والرؤية.أنصح الجميع بالبحث في Google عن "حاجز ذاكرة jvm"، فهو موضوع غير تافه ومهم للغاية (إذا قمت بتعديل البيانات المشتركة التي يتم الوصول إليها بواسطة سلاسل رسائل متعددة).بعد القيام بذلك، أنصحك بالنظر إلى فئات الحزمة java.util.concurrent التي تساعد على تجنب استخدام المزامنة الصريحة، والتي بدورها تساعد في إبقاء البرامج بسيطة وفعالة، وربما حتى منع الجمود.

أحد الأمثلة على ذلك هو ConcurrentLinkedDeque.جنبا إلى جنب مع نمط الأوامر فهو يسمح بإنشاء سلاسل عمليات عاملة عالية الكفاءة عن طريق حشو الأوامر في قائمة الانتظار المتزامنة - لا حاجة إلى مزامنة صريحة، ولا توجد حالات توقف تام محتملة، ولا حاجة إلى وضع Sleep() صريح، فقط قم باستقصاء قائمة الانتظار عن طريق استدعاء take().

باختصار:يحدث "مزامنة الذاكرة". بشكل ضمني عندما تبدأ سلسلة رسائل، تنتهي سلسلة رسائل، تقرأ متغيرًا متطايرًا، تفتح شاشة (تترك كتلة/وظيفة متزامنة) وما إلى ذلك.يؤثر هذا "التزامن" (بمعنى "المسح") الجميع يكتب القيام به قبل هذا الإجراء معين.في حالة ما سبق ذكره ConcurrentLinkedDeque, ، التوثيق "يقول":

تأثيرات تناسق الذاكرة:كما هو الحال مع المجموعات المتزامنة الأخرى ، فإن الإجراءات في مؤشر ترابط قبل وضع كائن في concurrentLinkedDeque يحدث من قبل الإجراءات اللاحقة للوصول إلى هذا العنصر أو إزالة هذا العنصر من concurrentLinkedDeque في موضوع آخر.

يعد هذا السلوك الضمني جانبًا ضارًا إلى حد ما لأن معظم مبرمجي Java الذين ليس لديهم خبرة كبيرة سوف يأخذون الكثير من المال بسببه.ثم تعثرت فجأة في هذا الموضوع بعد أن لم تفعل Java ما "من المفترض" القيام به في الإنتاج حيث يوجد عبء عمل مختلف - ومن الصعب جدًا اختبار مشكلات التزامن.

يعني متزامنة ببساطة أن المواضيع المتعددة إذا كانت مرتبطة كائن واحد يمكن أن تمنع القراءة القذرة والكتابة إذا تم استخدام كتلة متزامنة على كائن معين. لتعطيك المزيد من الوضوح، دعنا نأخذ مثالا:

class MyRunnable implements Runnable {
    int var = 10;
    @Override
    public void run() {
        call();
    }

    public void call() {
        synchronized (this) {
            for (int i = 0; i < 4; i++) {
                var++;
                System.out.println("Current Thread " + Thread.currentThread().getName() + " var value "+var);
            }
        }
    }
}

public class MutlipleThreadsRunnable {
    public static void main(String[] args) {
        MyRunnable runnable1 = new MyRunnable();
        MyRunnable runnable2 = new MyRunnable();
        Thread t1 = new Thread(runnable1);
        t1.setName("Thread -1");
        Thread t2 = new Thread(runnable2);
        t2.setName("Thread -2");
        Thread t3 = new Thread(runnable1);
        t3.setName("Thread -3");
        t1.start();
        t2.start();
        t3.start();
    }
}

لقد أنشأت اثنين من كائنات فئة MyRunnable، Runnable1 التي يتم مشاركتها مع الموضوع 1 والخيط 3 & Runnable2 يجري مشاركتها مع الموضوع 2 فقط. الآن عند بدء تشغيل T1 و T3 دون مزامنة، يتم استخدام إخراج PFB الذي يشير إلى أن كل من المواضيع 1 و 3 يؤثر في وقت واحد على قيمة Var حيث لمؤشر الترابط 2، Var لديه ذاكرته الخاصة.

Without Synchronized keyword

    Current Thread Thread -1 var value 11
    Current Thread Thread -2 var value 11
    Current Thread Thread -2 var value 12
    Current Thread Thread -2 var value 13
    Current Thread Thread -2 var value 14
    Current Thread Thread -1 var value 12
    Current Thread Thread -3 var value 13
    Current Thread Thread -3 var value 15
    Current Thread Thread -1 var value 14
    Current Thread Thread -1 var value 17
    Current Thread Thread -3 var value 16
    Current Thread Thread -3 var value 18

باستخدام Synchronzied، موضوع 3 في انتظار مؤلم 1 لإكمال في جميع السيناريوهات. هناك اثنين من الأقفال المكتسبة، واحدة على Runnable1 المشتركة بموجب الموضوع 1 والخيط 3 وآخر على Runnable2 مشترك في الموضوع 2 فقط.

Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -1 var value 12
Current Thread Thread -2 var value 12
Current Thread Thread -1 var value 13
Current Thread Thread -2 var value 13
Current Thread Thread -1 var value 14
Current Thread Thread -2 var value 14
Current Thread Thread -3 var value 15
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 17
Current Thread Thread -3 var value 18

بسيطة متزامنة تعني عدم وجود خيوطين يمكنهم الوصول إلى كتلة / الأسلوب في وقت واحد. عندما نقول أن أي كتلة / طريقة لفئة متزامنة، فإنه يعني أن مؤشر ترابط واحد فقط يمكنه الوصول إليه في وقت واحد. داخليا الخيط الذي يحاول الوصول إليه أولا تأخذ قفل على هذا الكائن وعلى طول هذا القفل غير متاح لا يمكن لأي ترابط آخر الوصول إلى أي من الأساليب / الكتل المتزامنة من هذا المثال من هذا الفصل.

ملاحظة يمكن لخيط آخر الوصول إلى طريقة نفس الكائن غير المعرف ليتم مزامنة. يمكن للخيط إصدار القفل عن طريق الاتصال

Object.wait()

متزامنة هي كلمة رئيسية في Java والتي يتم استخدامها لتحدثها قبل العلاقة في بيئة متعددة الترددات لتجنب عدم تناسق الذاكرة وخطأ تداخل الخيط.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top