Utilizarea sincronizate - 1

"Bună, Amigo!"

— Da, sunt aici, sunt aici.

„Astăzi, vă voi spune despre utilizarea sincronizate în practică.”

„Când un program are multe obiecte și fire de execuție, se întâmplă adesea ca mai multe fire de execuție să funcționeze simultan cu același obiect. În acest fel, firele de execuție interferează unele cu altele.”

— Da, știu deja asta.

„Deci, să presupunem că aveți un obiect care este accesat de mai multe fire. Puteți face două lucruri pentru a evita problemele.”

„Primul este de a folosi blocuri sincronizate pentru a încheia fiecare locație în care este accesat obiectul. Dar această abordare poate să nu funcționeze dacă un programator scrie cod care accesează obiectul direct, fără un bloc sincronizat.”

„Prin urmare, o a doua abordare este folosită de cele mai multe ori – făcând obiectul sigur pentru fire.” „Cu alte cuvinte, mecanismul sincronizat este construit în obiectul însuși: își declară metodele sincronizate și/sau învelește codul în metodele sale în blocuri sincronizate.”

„Deci, orice obiect pe care l-aș putea folosi din mai multe fire de execuție și acestea sunt aproape toate obiectele din program, trebuie să-l protejez pentru fire?”

„În general, da. În realitate, nu toate obiectele dintr-un program sunt folosite de fire diferite, dar de obicei sunt multe. Deci, atunci când începi să scrii cod pentru un fir și accesezi diverse obiecte din acesta, atunci cu fiecare apel de metodă ar trebui să vă întrebați: „Este acest apel în siguranță?”

"Sigur?"

„Thread-safe, ceea ce înseamnă că poate fi apelat în siguranță din mai multe fire.”

„Iată câteva exemple. Să presupunem că aveți un obiect String care este accesat din fire diferite. După cum ar fi trebuit să vă amintiți deja, String este imuabil - la fel ca toate celelalte tipuri primitive. Aceasta înseamnă că un obiect nu se schimbă după ce este creat . Aceasta înseamnă că este imposibil să „spărgi” un astfel de obiect. Toate obiectele imuabile sunt sigure pentru fire.”

— Ei bine, asta ușurează lucrurile.

— Acum, să presupunem că ai nevoie de un șir mutabil.

"Da, îmi amintesc. Există două tipuri de astfel de șiruri: StringBuffer și StringBuilder. StringBuffer este ca și StringBuilder, dar toate metodele sale sunt sincronizate. Este și thread-safe?"

„Da. Dacă trebuie să accesați un obiect StringBuilder din mai multe fire de execuție, trebuie să-l înlocuiți cu un StringBuffer. În caz contrar, mai devreme sau mai târziu firele îl vor schimba în același timp și îl vor „rupe””.

"Ce se întâmplă dacă obiectul care este accesat din fire diferite este un obiect al propriei mele clase? Trebuie să adaug sincronizat la metodele sale și în acest caz?"

"Da. Cel mai bine este să urmați această regulă: toate obiectele care vor fi accesate din fire diferite trebuie să fie sigure pentru fire."

— Înțeleg. Nu credeam că totul era atât de grav. Mulțumesc, Ellie.

„Cu plăcere. Sper că aceste sfaturi vă vor ajuta când Diego vă va oferi câteva dintre sarcinile sale ușoare. ☺”