una tipos superclase que polimorfismo objetos modificadores metodos lista instancia ejemplos clases clase atributos acceso abstracta java multithreading synchronization class object

tipos - superclase java



¿Cómo sincronizar una variable estática entre hilos que ejecutan diferentes instancias de una clase en Java? (5)

Hay varias formas de sincronizar el acceso a una variable estática.

  1. Use un método estático sincronizado. Esto se sincroniza en el objeto de clase.

    public class Test { private static int count = 0; public static synchronized void incrementCount() { count++; } }

  2. Sincronizar explícitamente en el objeto de la clase.

    public class Test { private static int count = 0; public void incrementCount() { synchronized (Test.class) { count++; } } }

  3. Sincronice en algún otro objeto estático.

    public class Test { private static int count = 0; private static final Object countLock = new Object(); public void incrementCount() { synchronized (countLock) { count++; } } }

El método 3 es el mejor en muchos casos porque el objeto de bloqueo no está expuesto fuera de su clase.

Sé que el uso de la palabra clave synchronize antes de un método trae sincronización a ese objeto. Es decir, 2 subprocesos que ejecutan la misma instancia del objeto se sincronizarán.

Sin embargo, dado que la sincronización está en el nivel del objeto, 2 hilos que ejecutan instancias diferentes del objeto no se sincronizarán. Si tenemos una variable estática en una clase Java a la que llama el método, nos gustaría que esté sincronizada 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 lock objeto que es estático y estamos utilizando la palabra clave synchronized para ese bloqueo, el count variables estáticas ahora está sincronizado en las instancias de la clase Test ?


Puedes sincronizar tu código sobre la clase. Eso sería más simple.

public class Test { private static int count = 0; private static final Object lock= new Object(); public synchronized void foo() { synchronized(Test.class) { count++; } } }

Espero que encuentres útil esta respuesta.


Si es cierto.

Si creas dos instancias de tu clase

Test t1 = new Test(); Test t2 = new Test();

Entonces t1.foo y t2.foo se sincronizan en el mismo objeto estático y, por lo tanto, se bloquean entre sí.


Si simplemente comparte un contador, considere usar un AtomicInteger u otra clase adecuada del paquete java.util.concurrent.atomic:

public class Test { private final static AtomicInteger count = new AtomicInteger(0); public void foo() { count.incrementAndGet(); } }


Si solo se trata de este número entero, también puede usar

Interlocked.Increment(count)

(el espacio de nombres es System.Threading).