ما هو الفرق بين الطريقة المتزامنة والكتلة المتزامنة في جافا؟ [مكرر

StackOverflow https://stackoverflow.com/questions/1149928

سؤال

هذا السؤال لديه بالفعل إجابة هنا:

ما هو الفرق بين الطريقة المتزامنة والكتلة المتزامنة في جافا؟

لقد كنت أبحث عن الإجابة على الشبكة، ويبدو أن الناس غير متأكد من هذا واحد :-(

لن يكون هناك اختلاف بين الاثنين، إلا أن كتلة الصناعة قد تكون أكثر تجميعية في نطاق وبالتالي ستكون القفل من وقت أقل؟

وفي حالة القفل على طريقة ثابتة، ما هو القفل المتخذ؟ ما معنى قفل على الفصل؟

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

المحلول

تستخدم الطريقة المتزامنة استقبال الطريقة كقفل (أي this للطرق غير الثابتة، والطبقة المرفوعة من أجل الأساليب الثابتة). Synchronized تستخدم الكتل التعبير كقفل.

وبالتالي فإن الطريقة التالية هي ما يعادلان من قفل المحتملين:

synchronized void mymethod() { ... }

void mymethod() {
  synchronized (this) { ... }
}

بالنسبة للطرق الثابتة، سيتم قفل الفصل:

class MyClass {
  synchronized static mystatic() { ... }

  static mystaticeq() {
    syncrhonized (MyClass.class) { ... }
  }
}

للكتل المتزامنة، يمكنك استخدام أي غيرnull كائن كقفل:

synchronized (mymap) {
  mymap.put(..., ...);
}

قفل نطاق

للطرق المتزامنة، سيتم عقد القفل طوال نطاق الأسلوب، في حين في synchronized Block، يتم احتجاز القفل إلا خلال هذا النطاق اللقطات (يعرف باسم القسم النقدي). في الممارسة العملية، يسمح ل JVM بالتحسين عن طريق إزالة بعض العمليات من synchronized تنفيذ كتلة إذا كان يمكن أن يثبت أنه يمكن القيام به بأمان.

نصائح أخرى

الطريقة المتزامنة هي اختصار. هذه:

class Something {
    public synchronized void doSomething() {
        ...
    }

    public static synchronized void doSomethingStatic() {
        ...
    }
}

هو، لجميع النوايا والأغراض، أي ما يعادل هذا:

class Something {
    public void doSomething() {
        synchronized(this) {
            ...
        }
    }

    public static void doSomethingStatic() {
        synchronized(Something.class) {
            ...
        }
    }
}

(أين Something.class هو كائن الفصل للفئة Something.)

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

نعم، هذا فرق واحد. الآخر هو أنه يمكنك الحصول على قفل على كائنات أخرى من this.

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

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

أقفال الطريقة المتزامنة على مثيل الكائنات الواردة في هذه الطريقة.

حيث يمكن أن تكون كتلة متزامنة قفل على أي كائن - عادة ما يتم تعريف Abect Abect ك Nutex كمتغير مثيل. هذا يسمح بمزيد من السيطرة على ما تكون الأقفال قيد التشغيل.

لن يكون هناك اختلاف بين الاثنين، إلا أن كتلة الصناعة قد تكون أكثر تجميعية في نطاق وبالتالي ستكون القفل من وقت أقل؟

نعم. أنت محق. على عكس synchronized الأساليب، يجب أن تحدد البيانات المتزامنة الكائن الذي يوفر القفل الجوهري.

مثال من Java Tutorial:

public void addName(String name) {
    synchronized(this) {
        lastName = name;
        nameCount++;
    }
    nameList.add(name);
}

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

لنفترض، على سبيل المثال، الفصل MsLunch لديه حقول مثيل، C1 و C2، والتي لا تستخدم أبدا معا. يجب أن تكون جميع تحديثات هذه الحقول synchronized, ، ولكن ليس هناك سبب لمنع تحديث C1 من التشويه مع تحديث C2 - والقيام بذلك تقلل من التزامن من خلال إنشاء حظر غير ضروري. بدلا من استخدام الأساليب المتزامنة أو استخدام القفل المرتبط بهذا، نقوم بإنشاء كائنين فقط لتوفير الأقفال.

وفي حالة القفل على طريقة ثابتة، ما هو القفل المتخذ؟ ما معنى قفل على الفصل؟

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

عند إجراء طريقة كما متزامنة ( عدم static ) :

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

إذا قمت بإجراء طريقة كما static synchronized :

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

تجد بدائل أفضل للمزامنة في هذا سؤال SE:

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

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