Resumo dos princípios básicos de java (oitenta e oito) - sincronizado também é reentrante

Link original ,

As fechaduras reentrantes, literalmente entendidas, são fechaduras que podem ser reintroduzidas.

Os bloqueios reentrantes, também chamados de bloqueios recursivos, significam que depois que a função externa do mesmo encadeamento adquire o bloqueio, a função recursiva interna ainda tem o código para adquirir o bloqueio, mas não é afetada.

No ambiente JAVA ReentrantLocke synchronizedsão bloqueio reentrante.

synchronizedÉ uma fechadura reentrante. Em uma classe, se o método synchronized 1 chamar o método synchronized 2, o método 2 pode ser executado normalmente, o que mostra que synchronized é um bloqueio reentrante. Caso contrário, quando o método 2 deseja adquirir um bloqueio, o bloqueio já foi adquirido quando o método 1 é executado, então o método 2 nunca será executado.

Em quais cenários os bloqueios reentrantes devem ser usados?

Os bloqueios reentrantes são usados ​​principalmente quando os encadeamentos precisam inserir o código da seção crítica várias vezes e os bloqueios reentrantes são necessários. Exemplos específicos, como quando um método sincronizado mencionado acima precisa chamar outro método sincronizado.

Qual é o princípio de implementação de bloqueios reentrantes?

Ao bloquear, você precisa determinar se o bloqueio foi adquirido. Se tiver sido adquirido, é determinado se o encadeamento que adquiriu o bloqueio é o encadeamento atual. Se for o segmento atual, adicione 1 ao número de aquisições. Se não for o segmento atual, você precisa esperar.

Ao liberar o bloqueio, você precisa subtrair 1 do número de aquisições de bloqueio e, em seguida, determinar se o número de vezes é 0. Se o número de vezes for 0, você precisará chamar o método de ativação de bloqueio para permitir que outros threads bloqueados no bloqueio tenham uma chance de execução.

A seguir está um exemplo implementado com synchronized:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

public class ReentrantTest implements Runnable {

  public synchronized void get() {

    System.out.println(Thread.currentThread().getName());

    set();

  }

  public synchronized void set() {

    System.out.println(Thread.currentThread().getName());

  }

  public void run() {

    get();

  }

  public static void main(String[] args) {

    ReentrantTest rt = new ReentrantTest();

    for(;;){

      new Thread(rt).start();

    }

  }

}

Não há impasse em todo o processo e alguns dos resultados de saída são os seguintes:

Thread-8492
Thread-8492
Thread-8494
Thread-8494
Thread-8495
Thread-8495
Thread-8493
Thread-8493

set()E get()ao mesmo tempo produza o nome do thread, indicando que não synchronizedhá deadlock mesmo se usado recursivamente , provando que é reentrante.

Resumindo

O texto acima é todo o conteúdo deste artigo. Espero que o conteúdo deste artigo tenha um determinado valor de referência para o seu estudo ou trabalho. Obrigado pelo seu apoio ao Scripthome. Se você quiser saber mais sobre isso, verifique os links relacionados abaixo

Acho que você gosta

Origin blog.csdn.net/lsx2017/article/details/113922446
Recomendado
Clasificación