Sé que usar la synchronize
palabra clave antes de un método trae sincronización a ese objeto. Es decir, se sincronizarán 2 subprocesos que ejecutan la misma instancia del objeto.
Sin embargo, dado que la sincronización se realiza a nivel de objeto, no se sincronizarán 2 subprocesos que ejecutan diferentes instancias del objeto. Si tenemos una variable estática en una clase Java a la que llama el método, nos gustaría que se sincronizara en todas las instancias de la clase. Las dos instancias se ejecutan en 2 subprocesos diferentes.
¿Podemos lograr la sincronización de la siguiente manera?
public class Test
{
private static int count = 0;
private static final Object lock= new Object();
public synchronized void foo()
{
synchronized(lock)
{
count++;
}
}
}
¿Es cierto que, dado que hemos definido un objeto lock
que es estático y estamos usando la palabra clave synchronized
para ese bloqueo, la variable estática count
ahora está sincronizada en todas las instancias de la clase Test
?
fuente
Respuestas:
Hay varias formas de sincronizar el acceso a una variable estática.
Utilice un método estático sincronizado. Esto se sincroniza con el objeto de clase.
Sincronizar explícitamente en el objeto de clase.
Sincronice con algún otro objeto estático.
El método 3 es el mejor en muchos casos porque el objeto de bloqueo no se expone fuera de su clase.
fuente
Test.class
y arruinarle el día. Además, la inicialización de clases se ejecuta con un bloqueo en la clase retenida, por lo que si tienes inicializadores de clases locos, puedes darte dolores de cabeza.volatile
no ayudacount++
porque es una secuencia de lectura / modificación / escritura. Como se señaló en una respuesta diferente,java.util.concurrent.atomic.AtomicInteger
probablemente sea la elección correcta aquí.Test.class
.this
sería el bloqueo para métodos sincronizados no estáticosSi simplemente está compartiendo un contador, considere usar un AtomicInteger u otra clase adecuada del paquete java.util.concurrent.atomic:
fuente
Si es cierto.
Si crea dos instancias de su clase
Entonces t1.foo y t2.foo se sincronizan en el mismo objeto estático y, por lo tanto, se bloquean entre sí.
fuente
Puede sincronizar su código sobre la clase. Eso sería lo más sencillo.
Espero que encuentre útil esta respuesta.
fuente
Test.class
y afectar el comportamiento. Esta es la razón por la quelock
podría preferirse la sincronización .También podemos usar ReentrantLock para lograr la sincronización de variables estáticas.
fuente