Saltearse al contenido

Sincronización

Un bloque sincronizado en Java marca un método o un bloque de código como sincronizado. Un bloque sincronizado en Java solo puede ser ejecutado por un único hilo a la vez (dependiendo de cómo lo usemos). Los bloques sincronizados de Java pueden, por lo tanto, usarse para evitar condiciones de carrera. Aquí explicaremos en más detalle cómo funciona la palabra clave synchronized de Java.

Utilidades de concurrencia de Java

El mecanismo de sincronización fue el primer mecanismo de Java para sincronizar el acceso a objetos compartidos por múltiples hilos. Sin embargo, este no es muy avanzado. Por eso, Java 5 obtuvo un conjunto completo de clases de utilidad de concurrencia para ayudar a los desarrolladores a implementar un control de concurrencia más granular que el que se obtiene con synchronized. Esto lo veremos en otra clase.

La palabra clave synchronized de Java

Los bloques sincronizados en Java se marcan con la palabra clave synchronized. Un bloque sincronizado en Java está sincronizado sobre algún objeto. Todos los bloques sincronizados que están sincronizados en el mismo objeto solo pueden tener un hilo ejecutándose dentro de ellos a la vez. Todos los demás hilos que intentan entrar en el bloque sincronizado se bloquean hasta que el hilo dentro del bloque sincronizado sale del bloque.

La palabra clave synchronized se puede usar para marcar cuatro tipos diferentes de bloques:

  1. Métodos de instancia
  2. Métodos estáticos
  3. Bloques de código dentro de métodos de instancia
  4. Bloques de código dentro de métodos estáticos

Estos bloques se sincronizan en diferentes objetos. El tipo de bloque sincronizado que necesitemos depende de la situación concreta. Aquí explicaremos los tipos de instancia sin tratar los casos estáticos.

Métodos de instancia sincronizados

Sea el siguiente método de instancia sincronizado:

1
public class MiContador {
2
private int cuenta = 0;
3
4
public synchronized void sumar(int valor) {
5
this.cuenta += valor;
6
}
7
}

Observemos el uso de la palabra clave synchronized en la declaración del método sumar(). Esto le dice a Java que el método está sincronizado.

Un método de instancia sincronizado en Java está sincronizado en la instancia (objeto) que posee el método. Por lo tanto, cada instancia tiene sus métodos sincronizados, sincronizados en un objeto diferente: la instancia propietaria.

Solo un hilo por instancia puede ejecutarse dentro de un método de instancia sincronizado. Si existe más de una instancia, entonces un hilo a la vez puede ejecutarse dentro de un método de instancia sincronizado por instancia. Un hilo por instancia.

Esto es cierto para todos los métodos de instancia sincronizados del mismo objeto (instancia). Así, en el siguiente ejemplo, solo un hilo puede ejecutarse dentro de cualquiera de los dos métodos sincronizados. Un hilo en total por instancia:

1
public class MiContador {
2
private int cuenta = 0;
3
4
public synchronized void sumar(int valor) {
5
this.cuenta += valor;
6
}
7
8
public synchronized void restar(int valor) {
9
this.cuenta -= valor;
10
}
11
}