سؤال

أنا حقا جديد في جاوة وأنا قرأت ذلك synchronized هو "مكلف للغاية" في جافا. كل ما أريد أن أعرفه هو ما هو مكلف وكيف هو مكلف؟

شكرًا.

هل كانت مفيدة؟

المحلول

ربما ليس سيئا كما تفكر

اعتادت أن تكون فظيعة (والتي ربما تكون لماذا تقرأ أنها كانت "مكلفة للغاية"). هذه الميمات يمكن أن يستغرق وقتا طويلا للموت

كم هو مزامنة المزامنة؟

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

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

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

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

نصائح أخرى

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

انها مثل عنق الزجاجة.

إنه باهظ الثمن عند استخدام مؤشر ترابط واحد، لأنه يجب أن يتحقق على أي حال إذا سمح لتشغيله.

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

لم يتم العثور على نظرة عامة رفيعة المستوى حول كيفية العثور على أعمال المزامنة هنا

http://img20.imageshack.us/img20/2066/monitor28synchronizatioc.png.

مراقب نمط جافا

هذا ليس هذا محددا ل Java. يمكن اعتبار المزامنة "مكلفا" في أي بيئة متعددة الخيوط إذا لم تتم بشكل صحيح. سواء كان الأمر سيئا بشكل خاص في جافا، فأنا لا أعرف.

يمنع تركيبات من الجري بشكل متزامن إذا استخدموا نفس المورد. ولكن، لأنهم فعل استخدم نفس المورد، ليس هناك خيار أفضل (يجب القيام به).

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

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

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

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

هذه مقالة - سلعة في IBM في الواقع يلخص بشكل جيد للغاية النقاط الرئيسية وراء المزامنة.

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

تعطي الإجابات الأخرى مستوى جيد من التفاصيل الفنية التي لن أحاول تكرارها.

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

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

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

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