Синхронно метод и устройство Java (синхронизирано метод срещу блок)

Неведнъж съм чул от на Java програмисти, които синхронизират метод е просто удобен начин да записвате с синхронизирано блок в този момент.

Нека да се справят с това веднъж завинаги. И да ни помогне в тази забележителна книга, че всеки човек, независимо от вида на дейност със сигурност носи със себе си на хартия или в електронен вид, - "Java Virtual Machine спецификация" :).

На първо място, без да се правят каквито и да било жестове можете да се досетите, че в първия случай, улавяне и последващото освобождаване на монитора ще се проведе извън тялото на метода, а вторият проход - вътре.

Това означава, че за тези класове ще бъде генериран поне различен Кодът последователност. Ние се провери нашето предположение.

Разглобяване на компилиран клас-файл може да бъде произведен с помощта на командата: javap -C

Тук е резултат от разглобяване за първи клас:

За втора класа резултатът ще бъде:

Инструкции monitorenter и monitorexit използва за улавяне и освобождаване sootvtestvenno на монитора. Второ monitorexit необходимо за монитора в случай на изключения (изключение / грешки) в синхрон блок osobozhdeniya.

Това е твърдението на равенство на записи вече не е вярно.

Друг въпрос възниква, как се случва улавяне на монитора в първия случай. И все пак - кой вариант ще работи по-бързо.

Вече едва предположения не могат да направят е - необходимо е да се обърне към спецификациите на машината virtaulnyh Java (Java Virtual Machine спецификация).

В "7.14 синхронизация" четем следното:

1. синхронизирано метод обикновено не се осъществява чрез използване на monitorenter и monitorexit. Вместо това, тя просто се отличава по време на работа в постоянен фонд от ACC_SYNCHRONIZED знаме, което се установява чрез инструкциите позоваването метод. При позоваване на метод, за който е настроен ACC_SYNCHRONIZED, текущата нишка придобива монитор, се позовава на самия метод, и освобождава монитора дали позоваването на метод завършва обикновено или внезапно.

В допълнение, в раздел "8.13 Брави и синхронизация":

2. "А синхронизиран метод автоматично извършва операция за заключване, когато е извикана, тялото му не се изпълнява, ако процедурата за заключване е завършил успешно."

Това означава, че на теория, синхронизиран метод е да се извърши (малко) по-бързо, тъй като ACC_SYNCHRONIZED проверка флаг - е само част от процеса на проверка викането на метода (извършва се от виртуалната машина веднага след динамичен svyazvaniya, но преди същинското изпълнение на тялото на метода).

Тук се чете, и не ми е ясно ... това, което е първата опция трябва да бъде по-бързо? Да предположим, че имате няколко десетки потоци, които предизвикват същия метод. Метод по себе си съдържа само една критична точка (достъп до споделен ресурс). Всички останали - помощни изчисленията. Ами това е, за изображението, =) (и всъщност това се случва доста често). И в първия случай (използването на синхронизиран метод) е, че всички потоци, но един ще се чака за освобождаването на монитора, вместо на това, което ще трябва да се извършват независими една от друга операция?
IMHO всичко зависи от изпълнението.

И в двата случая, отнемане на монитора ще се случи и само една нишка в даден момент ще бъде в състояние да извърши критична точка.

Но Кодът последователност при нормална работа, в първия случай ще включва една инструкция, а вторият - осем:

Определяне на обекта, за който искате да заснемете екрана, в първия случай няма смисъл, тъй като обектът вече е известно (ние всъщност го наричат ​​метод). А синхронизирано блок тъй като мониторът може да бъде всичко, което желаете (в този случай - това).

Това е най-малко няколко инструкции, записани.

Обновено: О, аз разбирам какво искаш да кажеш. Съгласен съм. Но в статията се отнася до илюзията, че синхронизирано метод е еквивалентен на синхронизирано блок, който напълно съдържа тялото на метода, с времето на това.

Това е логично едно и също, че е такава замяна никога нямаше да промени резултатите от изпълнението.

Също така, аз не споделям мотивите си за изпълнение, тъй като и в двата случая ще се изпълнява едно и също действие (изземване наблюдава отделянето на монитор), само във втория случай тези действия са ясно разписани в байткод, и в първата JVM се знае, че тяхната което трябва да се изпълни.

Ако греша, моля, поправете ме.