La sincronizzazione si riferisce al multithreading. Un blocco di codice sincronizzato può essere eseguito solo da un thread alla volta. Java supporta più thread per l'esecuzione. Ciò potrebbe comportare che due o più thread accedano allo stesso campo o oggetto. La sincronizzazione è un processo che consente a tutti i thread paralleli di un programma di essere eseguiti in modo sincrono. La sincronizzazione evita errori di coerenza della memoria causati da un accesso incoerente alla memoria condivisa. Quando un metodo viene dichiarato come sincronizzato, il thread mantiene un monitor per l'oggetto il cui metodo viene eseguito. Se un altro thread sta eseguendo un metodo sincronizzato, il tuo thread si bloccherà finché l'altro thread non rilascerà il monitor. La sincronizzazione viene ottenuta in Java utilizzando una parola riservata
synchronized
. Puoi usarlo nelle tue classi definendo metodi o blocchi sincronizzati. Non potrai utilizzare synchronized
variabili o attributi in una definizione di classe.
Blocco a livello di oggetto
Si tratta di un meccanismo per sincronizzare un metodo non statico o un blocco di codice non statico in modo tale che solo un thread possa eseguire un determinato blocco o metodo su una determinata istanza di una classe. Questa operazione dovrebbe essere eseguita ogni volta che è necessario rendere sicuro il thread di dati a livello di istanza. Esempio:public class DemoClass{
public synchronized void demoMethod(){}
}
O
public class DemoClass{
public void demoMethod(){
synchronized (this) {
//other thread safe code
}
}
}
O
public class DemoClass{
private final Object lock = new Object();
public void demoMethod(){
synchronized (lock) {
//other thread safe code
}
}
}
Blocco a livello di classe
Impedisce a più thread di accedere a un blocco sincronizzato durante l'esecuzione in una qualsiasi delle istanze disponibili della classe. Ciò significa che se sono presenti 100 istanze della classe durante l'esecuzione del programmaDemoClass
, solo un thread in quel momento sarà in grado di essere eseguito demoMethod()
in ciascuno dei casi e tutti gli altri casi verranno bloccati per gli altri thread. Ciò è necessario quando è necessario rendere sicuro il thread di dati statici.
public class DemoClass{
public synchronized static void demoMethod(){}
}
O
public class DemoClass{
public void demoMethod(){
synchronized (DemoClass.class) {
//other thread safe code
}
}
}
O
public class DemoClass
{
private final static Object lock = new Object();
public void demoMethod(){
synchronized (lock) {
//other thread safe code
}
}
}
Alcune note importanti
- La sincronizzazione in Java garantisce che due thread non possano eseguire un metodo sincronizzato contemporaneamente o in parallelo.
synchronized
può essere utilizzato solo con metodi e blocchi di codice. Questi metodi o blocchi possono essere statici o non statici.- Ogni volta che un thread entra in un metodo sincronizzato o blocca, acquisisce un blocco e ogni volta che un thread esce da un metodo sincronizzato o blocca, la JVM rilascia il blocco. Il blocco viene rilasciato anche se il thread lascia il metodo sincronizzato dopo il completamento a causa di eventuali errori o eccezioni.
synchronized
in Java , ciò significa che se un metodo sincronizzato chiama un altro metodo sincronizzato che richiede lo stesso blocco, il thread corrente che detiene il blocco può accedere a quel metodo senza acquisire il blocco.- Синхронизация в Java будет бросать
NullPointerException
если an object используемый в синхронизированном блоке null. Например, в вышеприведенном примере codeа, если замок инициализируется Hownull
, синхронизированный (lock) броситNullPointerException
. - Синхронизированные методы в Java вносят дополнительные затраты на производительность вашего applications. Так что используйте синхронизацию, когда она абсолютно необходима. Кроме того, рассмотрите вопрос об использовании синхронизированных блоков codeа для синхронизации только критических секций codeа.
- Вполне возможно, что и статический и не статический синхронизированные методы могут работать одновременно or параллельно, потому что они захватывают замок на другой an object.
- В соответствии со спецификацией языка вы не можете использовать
synchronized
в конструкторе это приведет к ошибке компиляции. - Не синхронизируйте по не финальному (no final) полю, потому что link, на не финальное поле может измениться в любое время, а затем другой поток может получить синхронизацию на разных an objectх и уже не будет ниHowой синхронизации вообще. Лучше всего использовать класс
String
, который уже неизменяемый и финальный.
GO TO FULL VERSION