Programação altamente concorrente multithread (2) - introdução e customização de bloqueios reentrantes

Antecedentes:

  O que é "reentrante"? Reentrante significa que um encadeamento adquiriu um bloqueio e pode adquiri-lo novamente sem um conflito. O objetivo dos bloqueios reentrantes é evitar bloqueios.Os sincronizados e ReentrantLock em Java são bloqueios reentrantes.

  // bloqueio de reentrada sincronizada 
    private  void test () {
         //   adquire o bloqueio pela primeira vez 
        sincronizado ( this ) {
             while ( true ) {
                 //   adquire o mesmo bloqueio pela segunda vez 
                sincronizado ( this ) { 
                    System.out.println ( "ReentrantLock!" ); 
                } 
                Tente { 
                    Thread.sleep ( 1000 ); 
                } catch (InterruptedException e) { 
                    e.printStackTrace (); 
                }
            }
        } 
    } 

  // ReentrantLock 锁 重 入 lock 
    Lock lock = new ReentrantLock ();
    private  void test1 () { 
        lock.lock (); 
        tente { 
            test2 (); 
        } finalmente { 
            lock.unlock (); 
        } 
    } 
    private  void test2 () { 
        lock.lock (); 
        tente { 
            System.out.println ( "ReentrantLock!" ); 
        } finalmente { 
            lock.unlock (); 
        } 
    }

1. Bloqueio não reentrante personalizado

  O chamado bloqueio não reentrante, ou seja, se o encadeamento atual executar um método que já adquiriu o bloqueio, quando o método tentar adquirir o bloqueio novamente, ele não será bloqueado. O segmento a seguir executa o método test1 () para adquirir o bloqueio primeiro e, em seguida, executa o método test2 () para não executar a lógica em test2 () .O bloqueio deve ser liberado primeiro.

// Classe de bloqueio não reentrada 
Lock {
     // Se o booleano privado isLocked = false ; // Use lock público sincronizado void lock () {
         while (isLocked) {// Já ocupado,
             tente {
                 this .wait (); // Aguardando 
            } catch (InterruptedException e) { 
                e.printStackTrace (); 
            } 
        } 
        isLocked = true ; // Modifica o sinalizador conforme ocupado 
    } // Libera o bloqueio público sincronizado
     

    
      

    
      void unLock () { 
        isLocked = false ; // Modifica o sinalizador como desocupado 
        notify (); // Desperta o thread em espera 
    } 

}
 ============ Use ========== = 
    Lock lock = new Lock (); 

    public  void test1 () { 
        lock.lock (); 
        test2 (); 
        lock.unLock (); 
    } 

    private  void test2 () { 
        lock.lock (); 
        // ... 
        lock .unLock (); 
    }

2. Bloqueio reentrante personalizado

   Processo:

  1. Defina o número de identificadores de ocupação de bloqueio, threads de armazenamento e bloqueios de thread retidos;
  2. Usar bloqueio: determine se está ocupado e se o encadeamento atual não é igual ao encadeamento de armazenamento, se as condições atenderem à entrada aguardar, se não atender, modifique o sinalizador de ocupação, o encadeamento de armazenamento é o encadeamento atual, o número de bloqueios de encadeamento +1;
  3. Libere o bloqueio: determine se o encadeamento atual é igual ao encadeamento de armazenamento, o número de bloqueios de encadeamento é -1 quando as condições forem atendidas, quando o número de bloqueios de encadeamento = 0, modifique o sinalizador de ocupação, ative o encadeamento em espera e defina o encadeamento de armazenamento como nulo;
// 可重入锁
classe relock {
     // 是否占用
    private  boolean isLocked = false ;
    segmento privado lockedBy = null ; // 存储线程
    privada  int holdCount = 0 ;
    // 使用锁
    pública  sincronizado  vazio lock () lança InterruptedException { 
        Tópico t = Thread.currentThread ();
        while (isLocked && lockedBy! = t) { 
            wait (); 
        } 
        isLocked = true; 
        lockedBy = t; 
        holdCount ++ ; 
    } 
    // unlock 锁
    desbloqueio público  anulado sincronizado  () {
         if (Thread.currentThread () == lockedBy) { 
            holdCount - ;
            if (holdCount == 0 ) { 
                isLocked = false ; 
                notify (); 
                lockedBy = null ; 
            }         
        }         
    } Público int
     getHoldCount () {
         return holdCount; 
    } 
}
 ============== class ===============
 classe pública  LockTest { 
    ReLock lock = new ReLock ();
    public void test1 () lança InterruptedException { 
        lock.lock (); 
        System.out.println (lock.getHoldCount ()); 
        test2 (); 
        bloquear desbloquear(); 
        System.out.println (lock.getHoldCount ()); 
    } // 入 重 入public void test2 () lança InterruptedException { 
    
      
        lock.lock ();
        System.out.println (lock.getHoldCount ()); 
        // ................... 
        lock.unlock (); 
        System.out.println (lock.getHoldCount ()); 
    } 
    public  static  void main (String [] args) lança InterruptedException { 
        LockTest lockTest = new LockTest (); 
        lockTest.test1 ();            
        Thread.sleep ( 1000 );        
        System.out.println (lockTest.lock.getHoldCount ()); 
    } 

}

Acho que você gosta

Origin www.cnblogs.com/huangrenhui/p/12711778.html
Recomendado
Clasificación