Синхронизирани изрази на Java
Инструкциитеsynchronizedви позволяват да изпълните синхронизиран код, който може да блокира произволен обект, а не само текущия, или да намали продължителността на блокирането, разширявайки влиянието му само върху част от метода. Синхронизираният оператор се състои от две части - препратка към обекта, чието заключване се иска, и част от кода, който се изпълнява след 3:1, когато заключването е получено. Общата синтактична форма на синхронизираното изявление е
изразъттрябва да се изчисли към препратка към обект. След получаване на правото на заключване, кодовият блокИнструкциясе изпълнява, след завършването на което заключването се освобождава - заключването се освобождава дори ако във фрагмента на кода наИнструкцияе хвърлено необработено изключение. Декларацията на синхронизирания метод, обсъдена по-горе, всъщност е съкратена синтактична конструкция за описване на метод, чието тяло е затворено в синхронизиран оператор, който използва препратката this, за да посочи блокиращия обект.
Помислете за метод, който замества стойността на всеки елемент от масив с абсолютна стойност и използва синхронизирания оператор, който регулира достъпа до масива:
/** Присвояване на елементите на целочисления масив абсолютните стойности на текущите стойности */
public static void abs(int[] values)
Синхронизираният оператор в тялото на конструктора придобива заключването на обекта на класа върху обекта на тялото по същия начин, по който го прави статичен метод на синхронизиран клас. Би било погрешно да се използва тази препратка за синхронизация, тъй като тя сочи към различни обекти при всяко извикване на конструктора, така че заключването на текущия (този) обект не е в състояние да предотврати възможността за едновременнодостъп до nextID от множество нишки. Също така е неправилно да се използва Object. getclass - в разширен клас като AttributedBody ще върне препратка към обекта на класа за AttributedBody, но не и за Body и отново вместо едно заключване ще бъдат създадени няколко заключения и еднократният достъп до данни ще бъде напълно възможен. Има едно просто правило: винаги трябва да защитавате статичните данни със заключване на клас обект на класа, в който са декларирани.
В много случаи обаче е по-удобно да се защити код вместо синхронизирани изрази, като се използват синхронизирани методи. (Например, в класа Body бихме могли да обвием кода, който осъществява достъп до полето nextID в статичен синхронизиран метод getNextID.) Само вашите собствени знания и практически опит ще ви помогнат да отговорите на въпроса кога да използвате единия подход и кога другия.
И накрая, способността на синхронизираните оператори да изискват заключване на произволни обекти прави възможно извършването на синхронизация от страна на клиента, както вече показахме с abs static метода, който замества стойностите на елементите на масива със съответните абсолютни стойности. Тази способност е много важна не само от гледна точка на защита на кода на обекти, които нямат синхронизирани методи, но и за синхронизиране на последователности от извиквания на обекти. Ще разгледаме това подробно в следващия раздел.
Източник: Арнолд, Кен, Гослинг, Джеймс, Холмс, Дейвид. Език за програмиране Java. 3-то изд.: Пер. от английски. - М .: Издателство "Уилям", 2001. - 624 с. : аз ще. - Парал. синигер. английски