Java: Cosa, se non altro, è bloccato da metodi sincronizzati a parte l'oggetto a cui appartengono?

StackOverflow https://stackoverflow.com/questions/609963

Domanda

Ora, non sono sicuro che questa sia una domanda stupida, per favore abbi pazienza se lo è.

Il blocco su un oggetto "ricorsivo", i. e. se due oggetti hanno riferimenti a un terzo oggetto nei loro campi e un thread sta eseguendo un metodo sincronizzato su uno dei due, un altro thread può accedere al terzo oggetto?

// a and b are some objects that implement Runnable
// they both reference the same third object
a.ref = c;
b.ref = c;

// a is run in a thread and processes some data in a loop for a long time
// the method the loop belongs to is declared synchronized
threadA = new Thread(a);
threadA.start();

a.someSyncedMethod(); // this would block ...
b.ref.someOtherSyncedMethod(); // ... but would this?
a.ref.someOtherSyncedMethod(); // ... and how about this?
È stato utile?

Soluzione

Vale la pena separare i concetti di " a lock " e "bloccare un oggetto". Non c'è idea reale di "bloccare un oggetto" - c'è " acquisizione (e rilascio) " il blocco associato a un oggetto. Sì, sembra che io sia pignolo, ma la distinzione è importante perché se parli di un oggetto bloccato, sembra che nessun altro thread sarà in grado di cambiare qualcosa nell'oggetto mentre quel blocco è tenuto.

Invece, significa solo che nessun altro thread sarà in grado di acquisire lo stesso blocco mentre il blocco viene tenuto. Non esiste una relazione diretta tra il blocco e uno qualsiasi dei contenuti dell'oggetto a cui è associato il blocco.

Metodi dichiarati " sincronizzati " acquisire il blocco associato all'istanza dell'oggetto a cui appartengono. Questo fa attendere solo altri metodi sincronizzati sullo stesso oggetto e istruzioni sincronizzate che si sincronizzano esplicitamente su di esso.

Personalmente non mi piacciono i metodi sincronizzati - mi piace renderlo più chiaro eseguendo la sincronizzazione esplicita su una variabile membro (privata, finale) che viene utilizzata solo per la sincronizzazione.

Altri suggerimenti

a.someSyncedMethod(); // this would block ...

Solo se contrassegni il metodo di esecuzione con sincronizzato o hai il codice di esecuzione ThreadA in metodi sincronizzati.

Nella JVM, ogni oggetto possiede ciò che è noto come monitor. Solo un thread può possedere il monitor associato a un determinato oggetto alla volta. Sincronizzato è il mezzo con cui dici al thread corrente di andare a prendere il monitor prima di continuare.

Anche la classe stessa possiede un monitor per i metodi statici.

Il significato di un "blocco" (in realtà questa variante si chiama monitor) è interamente una convenzione, non vengono applicate restrizioni di accesso.

Il funzionamento si basa sul fatto che tutti gli oggetti siano ben educati e acquisiscano il blocco corrispondente prima di accedere ai dati. Solo incapsulando questo comportamento desiderato all'interno di una classe con controlli di accesso adeguati è possibile applicarlo per gli oggetti client.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top