Interbloqueo de subprocesos múltiples, bloqueo (6)

Interbloqueo de subprocesos múltiples, bloqueo (6)

  1. Interbloqueo: varios subprocesos retienen los recursos de los demás y luego forman un punto muerto .

    //死锁:多个线程互相抱着对方需要的资源,然后形成僵持
    public class DeadLock {
          
          
        public static void main(String[] args) {
          
          
            Makeup g1=new Makeup(0,"灰姑凉");
            Makeup g2=new Makeup(1,"白雪公主");
    
            g1.start();
            g2.start();
        }
    }
    
    //口红
    class Lipstick{
          
          
    
    }
    
    //镜子
    class Mirror{
          
          
    
    }
    
    class Makeup extends Thread{
          
          
        //需要的资源只有一份,用static来保证只有一份
        static Lipstick lipstick=new Lipstick();
        static Mirror mirror=new Mirror();
    
        int choice;//选择
        String girlName;//使用化妆品的人
    
        Makeup(int choice,String girlName){
          
          
            this.choice=choice;
            this.girlName=girlName;
        }
    
        @Override
        public void run() {
          
          
            // 化妆
            try {
          
          
                makeup();
            } catch (InterruptedException e) {
          
          
                e.printStackTrace();
            }
        }
    
        //化妆,互相持有对方的锁,就是需要拿到对方的资源
        private void makeup() throws InterruptedException {
          
          
            if (choice==0){
          
          
                synchronized (lipstick){
          
          //获得口红的锁
                    System.out.println(this.girlName+"获得口红的锁");
                    Thread.sleep(1000);
                 synchronized (mirror){
          
          //一秒钟之后获得镜子
                     System.out.println(this.girlName+"获得镜子的锁");
                 }
                }
            }else {
          
          
                synchronized (mirror){
          
          //获得镜子的锁
                    System.out.println(this.girlName+"获得镜子的锁");
                    Thread.sleep(2000);
                    synchronized (lipstick){
          
          //一秒钟之后获得口红
                        System.out.println(this.girlName+"获得口红的锁");
                    }
                }
    
            }
        }
    }
    
  2. Resolver este punto muerto es dejar que no se bloqueen mutuamente .

    //死锁:多个线程互相抱着对方需要的资源,然后形成僵持
    public class DeadLock {
          
          
        public static void main(String[] args) {
          
          
            Makeup g1=new Makeup(0,"灰姑凉");
            Makeup g2=new Makeup(1,"白雪公主");
    
            g1.start();
            g2.start();
        }
    }
    
    //口红
    class Lipstick{
          
          
    
    }
    
    //镜子
    class Mirror{
          
          
    
    }
    
    class Makeup extends Thread{
          
          
        //需要的资源只有一份,用static来保证只有一份
        static Lipstick lipstick=new Lipstick();
        static Mirror mirror=new Mirror();
    
        int choice;//选择
        String girlName;//使用化妆品的人
    
        Makeup(int choice,String girlName){
          
          
            this.choice=choice;
            this.girlName=girlName;
        }
    
        @Override
        public void run() {
          
          
            // 化妆
            try {
          
          
                makeup();
            } catch (InterruptedException e) {
          
          
                e.printStackTrace();
            }
        }
    
        //化妆,互相持有对方的锁,就是需要拿到对方的资源
        private void makeup() throws InterruptedException {
          
          
            if (choice==0){
          
          
                synchronized (lipstick){
          
          //获得口红的锁
                    System.out.println(this.girlName+"获得口红的锁");
                    Thread.sleep(1000);
    
                }
                synchronized (mirror){
          
          //一秒钟之后获得镜子
                    System.out.println(this.girlName+"获得镜子的锁");
                }
            }else {
          
          
                synchronized (mirror){
          
          //获得镜子的锁
                    System.out.println(this.girlName+"获得镜子的锁");
                    Thread.sleep(2000);
    
                }
                synchronized (lipstick){
          
          //一秒钟之后获得口红
                    System.out.println(this.girlName+"获得口红的锁");
                }
    
            }
        }
    }
    
  3. Maneras de evitar el estancamiento

    • Cuatro condiciones necesarias para el interbloqueo :
      • Condiciones mutuamente excluyentes : un recurso solo puede ser utilizado por un proceso a la vez.
      • Condiciones de solicitud y retención : cuando un proceso se bloquea al solicitar recursos, sigue reteniendo los recursos adquiridos
      • Condiciones de no privación : los recursos ya adquiridos por el proceso no pueden ser privados por la fuerza antes de que se agoten.
      • Condición de espera de circulación : se forma una especie de relaciones cíclicas y de otros recursos entre varios procesos.
    • Las cuatro condiciones necesarias para un punto muerto se enumeran arriba. Solo necesitamos encontrar una manera de romper una o más de estas condiciones para evitar el punto muerto.
  4. Cerrar con llave

    • A partir de JDK1.5, Java proporciona un mecanismo de sincronización de subprocesos más potente para lograr la sincronización mediante la definición explícita de objetos de bloqueo de sincronización. Los bloqueos de sincronización utilizan objetos de bloqueo para actuar como.
    • La clase ReentrantLock implementa Lock, que tiene la misma semántica de simultaneidad y memoria que sincronizada. En la realización del control seguro para subprocesos, ReentrantLock se usa más comúnmente, que puede mostrar bloqueos y liberar bloqueos.
    import java.util.concurrent.locks.ReentrantLock;
    
    //测试Lock锁
    public class TestLock {
          
          
        public static void main(String[] args) {
          
          
            TestLock2 testLock2=new TestLock2();
    
            new Thread(testLock2).start();
            new Thread(testLock2).start();
            new Thread(testLock2).start();
        }
    }
    
    class TestLock2 implements Runnable{
          
          
    
        int ticketNums=10;
        //定义lock锁
        private final ReentrantLock lock=new ReentrantLock();
    
        @Override
        public void run() {
          
          
            while (true){
          
          
    
                try{
          
          
                    lock.lock();//加锁
                    if (ticketNums>0){
          
          
                        try {
          
          
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
          
          
                            e.printStackTrace();
                        }
                        System.out.println(ticketNums--);
                    }else {
          
          
                        break;
                    }
    
                }finally {
          
          
                    //解锁
                    lock.unlock();
                }
    
            }
        }
    }
    
  5. Comparación de sincronizado y bloqueo

    • El bloqueo es un bloqueo de pantalla (abre y cierra manualmente el bloqueo, no olvides cerrar el bloqueo), sincronizado es un bloqueo implícito , que se libera automáticamente fuera de alcance.
    • El bloqueo solo tiene bloqueo de bloque de código, sincronizado tiene bloqueo de bloque de código y bloqueo de método
    • Al usar Bloqueos de bloqueo, JVM dedicará menos tiempo a programar subprocesos, mejor rendimiento. Y tiene un mejor desarrollo (proporcione más subcategorías)
    • Orden de prioridad:
      • Bloquear> Bloque de código de sincronización (ingresó al cuerpo del método y asignó los recursos correspondientes)> Método de sincronización (fuera del cuerpo del método)
    • Generalmente, usamos bloques de código sincrónicos y métodos sincrónicos.

Supongo que te gusta

Origin blog.csdn.net/Xun_independent/article/details/115015002
Recomendado
Clasificación