java - que - meta tags
Palabras clave sincronizadas anidadas (6)
Bloqueo ya obtanied por el hilo que ejecuta el método doSomething, por lo tanto, este subproceso puede ejecutar el método doSomethingElse.
Necesita dos objetos de bloqueo para crear una situación de punto muerto. En su caso, solo hay uno, por lo tanto, es imposible crear un punto muerto.
Tengo este código en Java:
public void doSomeThing() {
synchronized (this) {
doSomeThingElse();
}
}
public void doSomeThingElse() {
synchronized (this) {
// do something else
}
}
¿Puede este código bloquear? Quiero decir, ¿este código puede esperar para siempre?
Como se describe en la documentación de java para el bloqueo de Reentrant :
un hilo puede adquirir un candado que ya posee
El segundo bloque sincronizado está utilizando el mismo bloqueo y, por lo tanto, siempre será utilizable ya que el bloqueo ya se ha adquirido en el método externo.
No, no habrá un punto muerto.
El uso sincronizado en ambos casos this
así, si el bloque sincronizado en doSomeThing se ejecuta, ya tiene el bloqueo para que pueda ejecutar el método doSomeThingElse.
Si su código es tan simple, es equivalente a:
public synchronized void doSomeThing() {
doSomeThingElse();
}
public synchronized void doSomeThingElse() {
// do something else
}
En un bloque sincronizado puede volver a adquirir un candado que ya posee. El proveedor de bloqueo (esto) será adquirido por el primer hilo para ingresar doSomething (). Luego, en el método doSomethingElse () lo volverá a adquirir.
La razón para hacer esto? Bueno, no hay nada que decir que no haya otro hilo que ingrese doSomethingElse desde otro lado. Esto evitará que cualquier código ejecute el bloque en doSomething () hasta que el hilo en doSomethingElse () haya liberado "this".
Editar BTW, por supuesto, puede bloquear ... y bloqueará la ejecución de cualquier hilo que no tenga el objeto de sincronización. Sin embargo, no será (como se publicó) un punto muerto.
Si un hilo posee la cerradura en this
, entrará en otros métodos synchronized
/ bloque como cuchillo caliente en mantequilla.
Ya ha tomado el bloqueo del monitor en el primer sincronizado. Siempre debe asegurarse de que el diseño de concurrencia no haga que el rendimiento tenga un gran impacto.
Una forma de garantizar esto es sincronizando solo el enunciado / código requerido.
Digamos que ahora su código se verá algo así.
public void doSomeThing()
{
synchronized (this)
{
synchronized (this)
{
// do something else
}
}
}
Considerando que esto es lo que se requiere
public void doSomeThing()
{
doSomeThingElse();
}
public void doSomeThingElse()
{
synchronized (this)
{
// do something else
}
}