Metoda sincronizate și java unitate (metoda sincronizată vs bloc)

Am auzit în mod repetat, de la Java programatori metoda sincronizate este pur și simplu un mod convenabil de a înregistra cu un bloc sincronizat la această sincronizare.

Să se ocupe de această dată pentru totdeauna. Și să ne ajute în această carte remarcabilă că fiecare persoană, indiferent de tipul de activitate poartă cu siguranță cu el pe suport de hârtie sau în format electronic, - „Java Virtual Machine Specification“ :).

În primul rând, fără a face nici gesturi puteți ghici că, în primul caz, capturarea și eliberarea ulterioară a monitorului va avea loc în afara corpului metodei, iar al doilea pasaj - interior.

Asta este, pentru aceste clase vor fi generate secvențe de opcod cel puțin diferite. Verificăm ipoteza noastră.

Dezasamblarea de clasă fișier compilate pot fi produse folosind comanda: javap -c

Aici este rezultatul dezasambla pentru prima clasă:

Pentru a doua clasă rezultatul va fi:

Instrucțiuni monitorenter și monitorexit utilizate pentru a captura și elibera sootvtestvenno monitorului. osobozhdeniya a doua monitorexit necesare pentru monitor în cazul unor excepții (excepție / eroare) în blocul sincronizat.

Aceasta este afirmarea egalității de înregistrări nu mai este valabil.

apare o altă întrebare, cum se produce de captare monitorul în primul caz. Și totuși - opțiune care va rula mai repede.

Există deja o doar conjecturi nu poate face - este necesar să se apeleze la specificațiile mașinii virtaulnyh Java (Java Virtual Machine Specification).

În „7.14 sincronizare“ am citit următoarele:

1. O metodă sincronizate nu este implementată în mod normal, folosind monitorenter și monitorexit. Mai degrabă, este pur și simplu distinge în piscina constantă de rulare de pavilion ACC_SYNCHRONIZED, care este verificat de instrucțiunile de invocare a metodei. Atunci când invoca o metodă pentru care este setat ACC_SYNCHRONIZED, firul curent dobândește un monitor, invocă metoda în sine, și eliberează monitorul dacă invocarea metodei completează în mod normal, sau brusc.

În plus, în secțiunea „8.13 Locks și sincronizare“:

2. „O metodă sincronizată efectuează automat o operație de blocare atunci când este invocat, corpul său nu este executat până când operația de blocare a finalizat cu succes.“

Aceasta este, în teorie, o metodă de sincronizat trebuie să fie efectuată (ușor) mai rapid ca pavilion de verificare ACC_SYNCHRONIZED - este doar o parte a procesului de verificare apelul metodei (efectuată de către mașina virtuală imediat după svyazvaniya dinamic, dar înainte de executarea propriu-zisă a corpului metodei).

Aici sunt citite, și nu înțeleg destul de ... ceea ce este prima opțiune ar trebui să fie mai rapid? Să presupunem că aveți o duzină de câteva fluxuri care provoacă aceeași metodă. O metodă în sine conține doar o singură secțiune critică (accesul la o resursă partajată). Tot restul - calcule auxiliare. Ei bine este, pentru imagine =) (și, de fapt, acest lucru se întâmplă destul de des). Și în primul caz (utilizarea metodei sincronizate) este că toate fluxurile, dar va fi de așteptare pentru eliberarea monitorului în loc de ceea ce ar trebui să efectueze independent una de cealaltă operațiune?
IMHO totul depinde de punerea în aplicare.

În ambele cazuri, sechestrul monitorului se va produce și un singur fir la un moment dat va fi în măsură să efectueze secțiunea critică.

Dar secvența opcode în cazul funcționării normale, în primul caz va cuprinde o singură instrucțiune, al doilea - opt:

Definirea obiectului pentru care doriți să captura de ecran, în primul caz nu are sens, deoarece obiectul este deja cunoscut (o numim de fapt metoda). Un bloc sincronizat ca monitor poate fi orice doriți (în acest caz - aceasta).

Aceasta este cel puțin o pereche de instrucțiuni salvate.

Actualizat: Oh, înțeleg ce vrei să spui. Sunt de acord. Dar, în articol se referă la iluzia că o metodă sincronizată este echivalentă cu un bloc sincronizat care conține complet corpul metodei, cu calendarul acestei.

Este logic același lucru, adică, o astfel de înlocuire nu ar schimba rezultatele implementării.

De asemenea, nu împărtășesc raționamentul despre performanța, pentru că în ambele cazuri, va fi executat la aceeași acțiune (sechestrare a monitoriza eliberarea unui monitor), doar în al doilea caz aceste acțiuni sunt clar precizate în bytecode, și în primul JVM se știe că lor trebuie să efectuați.

Dacă am greșit, vă rugăm să corectați-mă.