Entrevista de la serie JUC de Java: codificación de interbloqueo y análisis de posicionamiento

Codificación de interbloqueo y análisis de ubicación

concepto

Deadlock se refiere al fenómeno de dos o más procesos que se esperan entre sí debido a la competencia por recursos durante el proceso de ejecución, si no hay interferencia externa no podrán avanzar. Si los recursos son suficientes, las solicitudes de recursos del proceso pueden satisfacerse y la posibilidad de un punto muerto es muy baja; de lo contrario, caerá en un punto muerto debido a la contención por recursos limitados.

imagen-20200318175441578

La causa del estancamiento

  • Recursos del sistema insuficientes
  • El orden en el que se ejecutan los procesos no es correcto
  • Mala asignación de recursos

Cuatro condiciones necesarias para el punto muerto

  • Mutuamente excluyentes
    • Solución: encapsular recursos compartidos mutuamente excluyentes en acceso simultáneo
  • Espera y espera
    • Solución: Cuando un proceso solicita recursos, requiere que no ocupe otros recursos, es decir, debe solicitar todos los recursos a la vez, este método conducirá a una baja eficiencia de los recursos.
  • No preventivo
    • Solución: Si el proceso no puede asignar recursos de manera inmediata, se requiere que no ocupe ningún otro recurso, es decir, solo puede realizar la operación de asignación cuando puede obtener todos los recursos requeridos al mismo tiempo.
  • Bucle esperando
    • Solución: Ordene los recursos y solicite que el proceso solicite los recursos en orden.

Código de interbloqueo

Creamos una clase de recursos, y luego dejamos que dos subprocesos mantengan sus propios bloqueos y, al mismo tiempo, intentamos adquirir otros, habrá un fenómeno de punto muerto

/**
 * 死锁小Demo
 * 死锁是指两个或多个以上的进程在执行过程中,
 * 因争夺资源而造成一种互相等待的现象,
 * 若无外力干涉那他们都将无法推进下去
 */

import java.util.concurrent.TimeUnit;

/**
 * 资源类
 */
class HoldLockThread implements Runnable{
    
    

    private String lockA;
    private String lockB;

    // 持有自己的锁,还想得到别人的锁

    public HoldLockThread(String lockA, String lockB) {
    
    
        this.lockA = lockA;
        this.lockB = lockB;
    }


    @Override
    public void run() {
    
    
        synchronized (lockA) {
    
    
            System.out.println(Thread.currentThread().getName() + "\t 自己持有" + lockA + "\t 尝试获取:" + lockB);

            try {
    
    
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }

            synchronized (lockB) {
    
    
                System.out.println(Thread.currentThread().getName() + "\t 自己持有" + lockB + "\t 尝试获取:" + lockA);
            }
        }
    }
}
public class DeadLockDemo {
    
    
    public static void main(String[] args) {
    
    
        String lockA = "lockA";
        String lockB = "lockB";

        new Thread(new HoldLockThread(lockA, lockB), "t1").start();

        new Thread(new HoldLockThread(lockB, lockA), "t2").start();
    }
}

Como resultado de la ejecución, el hilo principal no puede terminar

t1	 自己持有lockA	 尝试获取:lockB
t2	 自己持有lockB	 尝试获取:lockA

Cómo solucionar problemas de interbloqueos

Cuando tenemos un punto muerto, primero debemos usar el comando jps para ver el programa en ejecución

jps -l

Podemos ver la clase DeadLockDemo, que se ha estado ejecutando

imagen-20200318181504703

Utilice jstack para ver la información de la pila

jstack  7560   # 后面参数是 jps输出的该类的pid

Los resultados obtenidos

Found one Java-level deadlock:
=============================
"t2":
  waiting to lock monitor 0x000000001cfc0de8 (object 0x000000076b696e80, a java.lang.String),
  which is held by "t1"
"t1":
  waiting to lock monitor 0x000000001cfc3728 (object 0x000000076b696eb8, a java.lang.String),
  which is held by "t2"

Java stack information for the threads listed above:
===================================================
"t2":
        at com.moxi.interview.study.Lock.HoldLockThread.run(DeadLockDemo.java:42)
        - waiting to lock <0x000000076b696e80> (a java.lang.String)
        - locked <0x000000076b696eb8> (a java.lang.String)
        at java.lang.Thread.run(Thread.java:745)
"t1":
        at com.moxi.interview.study.Lock.HoldLockThread.run(DeadLockDemo.java:42)
        - waiting to lock <0x000000076b696eb8> (a java.lang.String)
        - locked <0x000000076b696e80> (a java.lang.String)
        at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

Al mirar la última línea, vemos Encontrado 1 punto muerto, es decir, hay un punto muerto

Supongo que te gusta

Origin blog.csdn.net/weixin_43314519/article/details/110283277
Recomendado
Clasificación