La sincronización se refiere a subprocesos múltiples. Un bloque de código sincronizado solo puede ser ejecutado por un hilo a la vez. Java admite múltiples subprocesos para la ejecución. Esto podría dar como resultado que dos o más subprocesos accedan al mismo campo u objeto. La sincronización es un proceso que permite que todos los subprocesos paralelos de un programa se ejecuten sincrónicamente. La sincronización evita errores de coherencia de la memoria causados por un acceso incoherente a la memoria compartida. Cuando un método se declara sincronizado, el hilo mantiene un monitor para el objeto cuyo método se está ejecutando. Si otro hilo está ejecutando un método sincronizado, su hilo se bloqueará hasta que el otro hilo libere el monitor. La sincronización se logra en Java mediante una palabra reservada
synchronized
. Puedes usarlo en tus clases definiendo métodos o bloques sincronizados. No podrá utilizar synchronized
variables o atributos en una definición de clase.
Bloqueo a nivel de objeto
Este es un mecanismo para sincronizar un método no estático o un bloque de código no estático de modo que solo un subproceso pueda ejecutar un bloque o método determinado en una instancia determinada de una clase. Esto debe hacerse siempre que necesite hacer que los subprocesos de datos a nivel de instancia sean seguros. Ejemplo:
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
}
}
}
Bloqueo a nivel de clase
Evita que varios subprocesos entren en un bloque sincronizado durante la ejecución en cualquiera de las instancias disponibles de la clase. Esto significa que si hay 100 instancias de la clase durante la ejecución de un programaDemoClass
, entonces solo un hilo en ese momento podrá ejecutarse demoMethod()
en cualquiera de los casos, y todos los demás casos serán bloqueados para otros hilos. Esto es necesario cuando necesita hacer que los subprocesos de datos estáticos sean seguros.
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
}
}
}
Algunas notas importantes
- La sincronización en Java garantiza que dos subprocesos no puedan ejecutar un método sincronizado al mismo tiempo o en paralelo.
synchronized
Solo se puede utilizar con métodos y bloques de código. Estos métodos o bloques pueden ser estáticos o no estáticos.- Cada vez que un subproceso ingresa a un método o bloque sincronizado, adquiere un bloqueo y cada vez que un subproceso sale de un método o bloque sincronizado, la JVM libera el bloqueo. El bloqueo se libera incluso si el subproceso abandona el método sincronizado una vez finalizado debido a errores o excepciones.
synchronized
En Java , esto significa que si un método sincronizado llama a otro método sincronizado que requiere el mismo bloqueo, el hilo actual que contiene el bloqueo puede ingresar a ese método sin adquirir el bloqueo.- Синхронизация в Java будет бросать
NullPointerException
если un objeto используемый в синхронизированном блоке null. Например, в вышеприведенном примере códigoа, если замок инициализируется Cómonull
, синхронизированный (lock) броситNullPointerException
. - Синхронизированные методы в Java вносят дополнительные затраты на производительность вашего aplicaciones. Так что используйте синхронизацию, когда она абсолютно необходима. Кроме того, рассмотрите вопрос об использовании синхронизированных блоков códigoа для синхронизации только критических секций códigoа.
- Вполне возможно, что и статический и не статический синхронизированные методы могут работать одновременно o параллельно, потому что они захватывают замок на другой un objeto.
- В соответствии со спецификацией языка вы не можете использовать
synchronized
в конструкторе это приведет к ошибке компиляции. - Не синхронизируйте по не финальному (no final) полю, потому что enlace, на не финальное поле может измениться в любое время, а затем другой поток может получить синхронизацию на разных un objetoах и уже не будет ниCómoой синхронизации вообще. Лучше всего использовать класс
String
, который уже неизменяемый и финальный.
GO TO FULL VERSION