No dudes en compartir nuestra página y códigos con otro, danos de tu ayuda para hacer crecer nuestra comunidad.
Solución:
Si declara el método como sincronizado (como lo estás haciendo al escribir public synchronized void addA()
) se sincroniza en el entero objeto, por lo que dos subprocesos que acceden a una variable diferente desde este mismo objeto se bloquearían entre sí de todos modos.
Si desea sincronizar solo una variable a la vez, para que dos subprocesos no se bloqueen entre sí al acceder a diferentes variables, debe sincronizarlos por separado en synchronized ()
bloques Si a
y b
eran referencias de objetos que usarías:
public void addA()
synchronized( a )
a++;
public void addB()
synchronized( b )
b++;
Pero como son primitivos, no puedes hacer esto.
Te sugiero que uses Entero atómico en cambio:
import java.util.concurrent.atomic.AtomicInteger;
class X
AtomicInteger a;
AtomicInteger b;
public void addA()
a.incrementAndGet();
public void addB()
b.incrementAndGet();
Sincronizado en la declaración del método hay azúcar sintáctica para esto:
public void addA()
synchronized (this)
a++;
En un static método es azúcar sintáctico para esto:
ClassA {
public static void addA()
synchronized(ClassA.class)
a++;
Creo que si los diseñadores de Java supieran entonces lo que se entiende ahora sobre la sincronización, no habrían agregado el azúcar sintáctico, ya que en la mayoría de los casos conduce a malas implementaciones de concurrencia.
De “Los tutoriales de Java™” en sincronizado métodos:
Primero, no es posible que dos invocaciones de métodos sincronizados en el mismo objeto para intercalar. Cuando un subproceso ejecuta un método sincronizado para un objeto, todos los demás subprocesos que invocan métodos sincronizados para el mismo objeto se bloquean (suspenden la ejecución) hasta que el primer subproceso termina con el objeto.
De “The Java™ Tutorials” sobre bloques sincronizados:
Las sentencias sincronizadas también son útiles para mejorar la concurrencia con sincronización detallada. Supongamos, por ejemplo, que la clase MsLunch tiene dos campos de instancia, c1 y c2, que nunca se usan juntos. Todas las actualizaciones de estos campos deben estar sincronizadas, pero no hay razón para evitar que una actualización de c1 se intercale con una actualización de c2 — y hacerlo reduce la concurrencia al crear bloqueos innecesarios. En lugar de usar métodos sincronizados o usar el bloqueo asociado con esto, creamos dos objetos únicamente para proporcionar bloqueos.
(Énfasis mío)
Supongamos que tienes 2 no entrelazado variables Por lo tanto, desea acceder a cada uno desde diferentes subprocesos al mismo tiempo. Necesitas definir el cerrar no en la clase de objeto en sí, sino en la clase Objeto como a continuación (ejemplo del segundo enlace de Oracle):
public class MsLunch
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc1()
synchronized(lock1)
c1++;
public void inc2()
synchronized(lock2)
c2++;
Sección de Reseñas y Valoraciones
Acuérdate de que tienes permiso de añadir una estimación certera si tropezaste tu aprieto en el momento justo.