يشير التزامن إلى تعدد العمليات. لا يمكن تنفيذ كتلة التعليمات البرمجية المتزامنة إلا بواسطة مؤشر ترابط واحد في المرة الواحدة. تدعم Java سلاسل عمليات متعددة للتنفيذ. قد يؤدي هذا إلى وصول خيطين أو أكثر إلى نفس الحقل أو الكائن. المزامنة هي عملية تسمح لجميع الخيوط المتوازية في البرنامج بالعمل بشكل متزامن. تعمل المزامنة على تجنب أخطاء تناسق الذاكرة الناتجة عن الوصول غير المتناسق إلى الذاكرة المشتركة. عندما يتم الإعلان عن أسلوب متزامن، يحتفظ مؤشر الترابط بمراقب للكائن الذي يتم تنفيذ طريقته. إذا كان مؤشر ترابط آخر ينفذ طريقة متزامنة، فسيتم حظر مؤشر الترابط الخاص بك حتى يقوم مؤشر الترابط الآخر بتحرير الشاشة. يتم تحقيق المزامنة في Java باستخدام كلمة محجوزة
synchronized
. يمكنك استخدامه في فصولك الدراسية عن طريق تحديد الأساليب أو الكتل المتزامنة. لن تتمكن من استخدامها synchronized
في المتغيرات أو السمات في تعريف الفئة.
قفل على مستوى الكائن
هذه آلية لمزامنة طريقة غير ثابتة أو كتلة تعليمات برمجية غير ثابتة بحيث يمكن لخيط واحد فقط تنفيذ كتلة أو طريقة معينة على مثيل معين لفئة ما. يجب أن يتم ذلك عندما تحتاج إلى جعل مؤشر ترابط البيانات على مستوى المثيل آمنًا. مثال:public class DemoClass{
public synchronized void demoMethod(){}
}
أو
public class DemoClass{
public void demoMethod(){
synchronized (this) {
//other thread safe code
}
}
}
أو
public class DemoClass{
private final Object lock = new Object();
public void demoMethod(){
synchronized (lock) {
//other thread safe code
}
}
}
قفل على مستوى الفصل
يمنع مؤشرات الترابط المتعددة من الدخول إلى كتلة متزامنة أثناء التنفيذ في أي من المثيلات المتاحة للفئة. هذا يعني أنه إذا كان هناك 100 مثيل للفئة أثناء تنفيذ البرنامجDemoClass
، فلن يتمكن سوى موضوع واحد فقط في ذلك الوقت من التنفيذ demoMethod()
في أي من الحالات، وسيتم حظر جميع الحالات الأخرى لسلاسل الرسائل الأخرى. يعد ذلك ضروريًا عندما تحتاج إلى جعل مؤشر ترابط البيانات الثابتة آمنًا.
public class DemoClass{
public synchronized static void demoMethod(){}
}
أو
public class DemoClass{
public void demoMethod(){
synchronized (DemoClass.class) {
//other thread safe code
}
}
}
أو
public class DemoClass
{
private final static Object lock = new Object();
public void demoMethod(){
synchronized (lock) {
//other thread safe code
}
}
}
بعض الملاحظات الهامة
- تضمن المزامنة في Java عدم تمكن خيطين من تنفيذ طريقة متزامنة في نفس الوقت أو بالتوازي.
synchronized
لا يمكن استخدامه إلا مع الأساليب وكتل التعليمات البرمجية. يمكن أن تكون هذه الأساليب أو الكتل ثابتة أو غير ثابتة.- عندما يدخل أي مؤشر ترابط إلى طريقة متزامنة أو يحظره، فإنه يحصل على قفل، وعندما يخرج مؤشر ترابط من طريقة متزامنة أو يحظر، يقوم JVM بتحرير القفل. يتم تحرير القفل حتى إذا ترك الخيط الطريقة المتزامنة بعد الانتهاء بسبب أي أخطاء أو استثناءات.
synchronized
في Java ، هذا يعني أنه إذا استدعت طريقة متزامنة طريقة متزامنة أخرى تتطلب نفس القفل، فيمكن للخيط الحالي الذي يحمل القفل الدخول إلى تلك الطريقة دون الحصول على القفل.- Синхронизация в Java будет бросать
NullPointerException
если an object используемый в синхронизированном блоке null. Например, в вышеприведенном примере codeа, если замок инициализируется Hownull
, синхронизированный (lock) броситNullPointerException
. - Синхронизированные методы в Java вносят дополнительные затраты на производительность вашего applications. Так что используйте синхронизацию, когда она абсолютно необходима. Кроме того, рассмотрите вопрос об использовании синхронизированных блоков codeа для синхронизации только критических секций codeа.
- Вполне возможно, что и статический и не статический синхронизированные методы могут работать одновременно or параллельно, потому что они захватывают замок на другой an object.
- В соответствии со спецификацией языка вы не можете использовать
synchronized
в конструкторе это приведет к ошибке компиляции. - Не синхронизируйте по не финальному (no final) полю, потому что link, на не финальное поле может измениться в любое время, а затем другой поток может получить синхронизацию на разных an objectх и уже не будет ниHowой синхронизации вообще. Лучше всего использовать класс
String
, который уже неизменяемый и финальный.
GO TO FULL VERSION