¿Puede alguien explicarme cómo se relacionan Reentrant lock
y deadlock
entre sí con el código de Java (pseudo) ejemplo?Bloqueo de reentrada y punto muerto con Java
Respuesta
Un mecanismo de bloqueo de reentrada permite que la rosca que sujeta la cerradura vuelva a entrar en una sección crítica. Esto significa que usted puede hacer algo como esto:
public synchronized void functionOne() {
// do something
functionTwo();
// do something else
// redundant, but permitted...
synchronized(this) {
// do more stuff
}
}
public synchronized void functionTwo() {
// do even more stuff!
}
En una cerradura no reentrante, que tendría una situación de bloqueo cuando intenta llamar desde functionTwo()
functionOne()
porque el hilo tendría que esperar a que el bloqueo .. .que se sostiene a sí mismo.
Deadlock, por supuesto, es la mala situación en la que el hilo 1 mantiene el bloqueo A y está esperando el bloqueo B mientras que el hilo 2 mantiene el bloqueo B y está esperando el bloqueo A. Por lo tanto, ninguno puede continuar. Este ejemplo de código crea un punto muerto:
hilopublic synchronized void deadlock() throws InterruptedException {
Thread th = new Thread() {
public void run() {
deadlock();
}
}.start();
th.join();
}
La vocación trata de esperar a que el subproceso generado, que a su vez no puede llamar deadlock()
hasta que el llamante ha salido. Ka-boom!
Un bloqueo de reentrada permitirá que el portador de la cerradura ingrese bloques de código incluso después de que ya haya obtenido la cerradura ingresando otros bloques de código. Un bloqueo no reentrante tendría el bloqueador de bloqueo bloqueándose sobre sí mismo, ya que tendría que liberar el bloqueo obtenido de otro bloque de código para volver a obtener ese mismo bloqueo para ingresar al bloqueo anidado que requiere bloque de código.
En lo que respecta al interbloqueo, si llama a un bloque de código protegido desde un bloque de código protegido, querrá un bloqueo de reentrada (o bloqueará mientras espera en sí mismo).
He aquí un ejemplo de estancamiento con ReentrantLock
class Deadlock {
private static final ReentrantLock l1 = new ReentrantLock();
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
public void run() {
System.out.println("A Trying to lock...");
l1.lock();
System.out.println("A Locked...");
try {
Thread t = new Thread(new Runnable() {
public void run() {
System.out.println("B Trying to lock...");
l1.lock();
System.out.println("B Must not print");
try {
} finally {
System.out.println("B Trying to unlock...");
l1.unlock();
System.out.println("B Unlocked...");
}
}
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
} finally {
System.out.println("A Trying to unlock...");
l1.unlock();
System.out.println("A Unlocked...");
}
}
});
t.start();
}
}
Para resolver estancamiento, comente llamada a t.join
, junto con encerrando try/catch.
Se produce un bloqueo muerto y un subproceso espera una condición que nunca se producirá.
El caso obvio es cuando intenta bloquear dos bloqueos, bloqueados en un orden diferente por diferentes hilos.
ReentrantLock lock1 = new ReentrantLock();
ReentrantLock lock2 = new ReentrantLock();
public void methodA() {
lock1.lock();
lock2.lock();
// do something and un lock both.
}
public void methodB() {
lock2.lock();
lock1.lock();
// do something and un lock both.
}
Como se puede ver que es posible que un hilo para llamar y obtener MethodA lock1 espera de Lock2, y otro hilo para llamar y obtener methodB Lock2 espera de lock1.
Sin embargo, es posible que un hilo de punto muerto en sí. Un ejemplo es ReentrantReadWriteLock porque no admite la actualización de un bloqueo de lectura para escribir el bloqueo.
ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
rwl.readLock().lock();
// do we need to update?
rwl.writeLock().lock(); // will wait for the readLock() to be released!
Una oportunidad oscura a un punto muerto a sí mismo es cuando cerraduras implicadas están utilizando. Un bloque inicializador estático está implícita hilo de seguridad por lo que un bloqueo se utiliza a pesar de que los bloques no son estáticas initialiser synchronized
class A {
private static int VALUE;
static {
Thread t = new Thread() {
public void run() {
// waits for the A class to load.
VALUE = someLongTask();
}
};
t.start();
// waits for the thread.
t.join();
}
}
vez que tienen un punto muerto!
- 1. punto muerto en código Java con semáforo y adquirir (int)
- 2. SqlException: Punto muerto
- 3. ¿Cuándo un punto muerto no es un punto muerto?
- 4. ¿Para qué se utiliza la reentrada de bloqueo en java?
- 5. Punto muerto del semáforo
- 6. Punto muerto en ThreadPoolExecutor
- 7. Diferencia entre condición de carrera y punto muerto
- 8. Punto muerto en ThreadPool
- 9. Punto muerto en Ruby join()
- 10. Cómo causar un punto muerto
- 11. Cómo depurar un punto muerto en Java usando Eclipse
- 12. Intento de punto muerto de ActiveRecord3
- 13. MySQL InnoDB bloqueo muerto en SELECT con bloqueo exclusivo (FOR UPDATE)
- 14. ¿Cómo encontrar AMBOS hilos de un punto muerto?
- 15. Java wait()/join(): ¿Por qué esto no es un punto muerto?
- 16. ¿Cómo provocar deliberadamente un punto muerto?
- 17. ¿Qué es el bloqueo y el concepto de reentrada en general?
- 18. Se requiere bloqueo y otros intentos de bloqueo no bloquean: ¿los bloqueadores C# son reentrantes?
- 19. Error al trabajar con MySQL "Se ha encontrado un punto muerto al intentar obtener un bloqueo; intente reiniciar la transacción"
- 20. Depuración de un punto muerto con el comando clrstack de Windbg
- 21. ¿Cómo codificar la regla de punto muerto de ajedrez?
- 22. ¿Alguien puede explicar el punto muerto del buffer de tubería?
- 23. Comportamiento de sincronización de reentrada con declaraciones sincronizadas
- 24. Transacción de Mysql en espera de bloqueo que ya está otorgado .. Esto está causando un punto muerto
- 25. Cola concurrente y de bloqueo en Java
- 26. ¿Cómo puedo evitar este aparente punto muerto de EhCache?
- 27. temporizador de C# sin reentrada
- 28. ¿Es posible que ConcurrentHashMap esté en "punto muerto"?
- 29. bloqueo de subproceso Java
- 30. Patrones para manejar un punto muerto SQL en C#?
Supongo que OP significa ejemplo usando la clase 'java.util.concurrent.locks.ReentrantLock' y no el bloque' synchronized'. –
@Victor Sorokin no estoy seguro de si está destinado a la capitalización o no. sin embargo, el concepto de alto nivel es exactamente el mismo, ya sea usando bloques 'sincronizados' o la clase' ReentrantLock'. – stevevls