Si sincronicé dos métodos en la misma clase, ¿pueden ejecutarse simultáneamente en el mismo objeto ? por ejemplo:
class A {
public synchronized void methodA() {
//method A
}
public synchronized void methodB() {
// method B
}
}
Sé que no puedo ejecutar methodA()
dos veces en el mismo objeto en dos hilos diferentes. lo mismo en methodB()
.
¿Pero puedo ejecutar methodB()
en un hilo diferente mientras methodA()
todavía se está ejecutando? (mismo objeto)
obj.methodB()
es sinónimo deA.methodB()
cuándomethodB()
esstatic
. Por lo tanto, sí, bloquearán (en el monitor de la clase, no del objeto)..class
objeto. Entonces si tienesclass A {static synchronized void m() {} }
. Y luego un hilo lo llamanew A().m()
adquiere bloqueo en elnew A()
objeto. Si luego otro hilo lo llamaA.m()
, ENTRA AL MÉTODO SIN PROBLEMA porque lo que busca es bloquear elA.class
objeto mientras NO HILOS poseen este tipo de bloqueo . Entonces, a pesar de que declaró el método,synchronized
en realidad ES ACCEDIDO por dos hilos diferentes AL MISMO TIEMPO . Por lo tanto: nunca use referencias de objetos para llamar a métodos estáticosEn el ejemplo, el método A y el método B son métodos de instancia (a diferencia de los métodos estáticos). Poner
synchronized
un método de instancia significa que el hilo debe adquirir el bloqueo (el "bloqueo intrínseco") en la instancia del objeto al que se llama el método antes de que el hilo pueda comenzar a ejecutar cualquier código en ese método.Si tiene dos métodos de instancia diferentes marcados como sincronizados y diferentes subprocesos llaman a esos métodos simultáneamente en el mismo objeto, esos subprocesos competirán por el mismo bloqueo. Una vez que un subproceso obtiene el bloqueo, todos los demás subprocesos quedan excluidos de todos los métodos de instancia sincronizados en ese objeto.
Para que los dos métodos se ejecuten simultáneamente, tendrían que usar diferentes bloqueos, como este:
donde la sintaxis del bloque sincronizado permite especificar un objeto específico en el que el subproceso en ejecución necesita adquirir el bloqueo intrínseco para ingresar al bloque.
Lo importante a entender es que a pesar de que estamos poniendo una palabra clave "sincronizada" en métodos individuales, el concepto central es el bloqueo intrínseco detrás de escena.
Así es como el tutorial de Java describe la relación:
El propósito del bloqueo es proteger los datos compartidos. Usaría bloqueos separados como se muestra en el código de ejemplo anterior solo si cada bloqueo protegía a diferentes miembros de datos.
fuente
static synchronized
osynchronized (A.class)
Java Thread adquiere un bloqueo de nivel de objeto cuando ingresa en un método Java sincronizado de instancia y adquiere un bloqueo de nivel de clase cuando ingresa en un método Java sincronizado estático .
En su caso, los métodos (instancia) son de la misma clase. Entonces, cuando un hilo ingresa al método o bloque sincronizado de Java, adquiere un bloqueo (el objeto en el que se llama el método). Por lo tanto, no se puede llamar a otro método al mismo tiempo en el mismo objeto hasta que se complete el primer método y se libere el bloqueo (en el objeto).
fuente
private final Object lock = new object();
con sincronizado para permitir que solo un hilo pueda ejecutar cualquiera de los métodos? GraciasEn su caso, sincronizó dos métodos en la misma instancia de clase. Por lo tanto, estos dos métodos no pueden ejecutarse simultáneamente en diferentes subprocesos de la misma instancia de clase A. Pero sí pueden en diferentes instancias de clase A.
es lo mismo que:
fuente
private final Object lock = new Object();
y ahora lo usolock
con bloque sincronizado en dos métodos, entonces su declaración será cierta? En mi opinión, Object es la clase principal de todos los objetos, por lo que incluso si los subprocesos están en una instancia diferente de la clase, solo uno puede acceder al código dentro del bloque sincronizado a la vez. Gracias.Desde el enlace de documentación de Oracle
Hacer métodos sincronizados tiene dos efectos:
Esto responderá a su pregunta: en el mismo objeto, no puede llamar al segundo método sincronizado cuando se está ejecutando el primer método sincronizado.
Eche un vistazo a esta página de documentación para comprender los bloqueos intrínsecos y el comportamiento del bloqueo.
fuente
Piense en su código como el siguiente:
Entonces, sincronizado a nivel de método simplemente significa sincronizado (esto). si algún subproceso ejecuta un método de esta clase, obtendría el bloqueo antes de comenzar la ejecución y lo mantendría hasta que finalice la ejecución del método.
De hecho, no es posible!
Por lo tanto, varios subprocesos no podrán ejecutar ningún número de métodos sincronizados en el mismo objeto simultáneamente.
fuente
Para toda claridad, es posible que tanto el método sincronizado estático como el sincronizado no estático puedan ejecutarse de manera simultánea o simultánea porque uno tiene bloqueo de nivel de objeto y otro bloqueo de nivel de clase.
fuente
La idea clave con la sincronización que no se hunde fácilmente es que tendrá efecto solo si se invocan métodos en la misma instancia de objeto (ya se ha resaltado en las respuestas y comentarios)
El siguiente programa de muestra es para señalar claramente lo mismo:
Observe la diferencia en la salida de cómo se permite el acceso simultáneo como se esperaba si se invocan métodos en diferentes instancias de objeto.
Ouput con noEffectOfSynchronizedAsMethodsCalledOnDifferentObjects () comentó: la salida está en orden methodA in> methodA Out .. methodB in> methodB Out
y Ouput con synchronizedEffectiveAsMethodsCalledOnSameObject () comentado : la salida muestra el acceso simultáneo del método A por Thread1 y Thread0 en la sección resaltada.
Aumentar el número de hilos lo hará aún más notable.
fuente
No, no es posible, si fuera posible, ambos métodos podrían actualizar la misma variable simultáneamente, lo que podría dañar fácilmente los datos.
fuente
Sí, pueden ejecutar simultáneamente ambos hilos. Si crea 2 objetos de la clase ya que cada objeto contiene solo un bloqueo y cada método sincronizado requiere bloqueo. Por lo tanto, si desea ejecutar simultáneamente, cree dos objetos y luego intente ejecutar utilizando esas referencias de objeto.
fuente
Lo está sincronizando en un objeto, no en una clase. Entonces no pueden correr simultáneamente en el mismo objeto
fuente
Dos subprocesos diferentes que ejecutan un método sincronizado común en el único objeto, ya que el objeto es el mismo, cuando un subproceso lo usa con el método sincronizado, tendrá que variar el bloqueo, si el bloqueo está habilitado, este subproceso irá al estado de espera, si el bloqueo está deshabilitado, puede acceder al objeto, mientras que accederá habilitará el bloqueo y lo liberará solo cuando se complete su ejecución. cuando llegue el otro subproceso, variará el bloqueo, ya que está habilitado esperará hasta que el primer subproceso complete su ejecución y libere el bloqueo puesto en el objeto, una vez que se libere el bloqueo, el segundo subproceso obtendrá acceso al objeto y habilitará el bloqueo hasta su ejecución. entonces la ejecución no será concurrente, ambos hilos se ejecutarán uno por uno,
fuente