O artigo compartilha 4 exemplos de explicação detalhada de sincronizado
1. Se deve adicionar palavras -chave sincronizadas
public class ThreadTest {public static void main (string [] args) {exemplo exemplo = new Exempli (); Thread t1 = new Thread1 (exemplo); Thread T2 = novo Thread1 (exemplo); t1.start (); t2.start (); }} Exemplo de classe {public sincronizado void escape () {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (interruptedException e) {e.printStackTrace (); } System.out.println ("escutas:" + i); }}} classe Thread1 estende o thread {Exemplo privado Exemplo; public Thread1 (exemplo de exemplo) {this.example = exemplo; } @Override public void run () {exemplo.excute (); }}O resultado da saída da palavra -chave sincronizada é a seguinte
Um conjunto de 0-4 será emitido primeiro e, em seguida, o próximo conjunto será emitido e os dois threads serão executados em sequência.
Excute: 0
EXCUTA: 1
EXCUTA: 2
EXCUTA: 3
EXCUTA: 4
Excute: 0
EXCUTA: 1
EXCUTA: 2
EXCUTA: 3
EXCUTA: 4
O resultado da saída da palavra -chave sincronizada é a seguinte
Dois threads executam o método de escutas simultaneamente e simultaneamente
Excute: 0
Excute: 0
EXCUTA: 1
EXCUTA: 1
EXCUTA: 2
EXCUTA: 2
EXCUTA: 3
EXCUTA: 3
EXCUTA: 4
EXCUTA: 4
2. Situação de threading de vários métodos
public class ThreadTest {public static void main (string [] args) {exemplo exemplo = new Exempli (); Thread t1 = new Thread1 (exemplo); Thread t2 = new Thread2 (exemplo); t1.start (); t2.start (); }} Exemplo de classe {public sincronizado void escape () {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (interruptedException e) {e.printStackTrace (); } System.out.println ("escutas:" + i); }} public sincronizado void exaustor1 () {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (interruptedException e) {e.printStackTrace (); } System.out.println ("Excute1:" + i); }}} classe Thread1 estende o thread {Exemplo privado Exemplo; public Thread1 (exemplo de exemplo) {this.example = exemplo; } @Override public void run () {exemplo.excute (); }} classe Thread2 estende o thread {Exemplo privado Exemplo; public Thread2 (exemplo de exemplo) {this.example = exemplo; } @Override public void run () {exemplo.excute1 (); }}Os resultados da execução são os seguintes
O mesmo é executado em sequência e um thread é executado antes que outro thread seja executado.
Excute: 0
EXCUTA: 1
EXCUTA: 2
EXCUTA: 3
EXCUTA: 4
Excute1: 0
Excute1: 1
Excute1: 2
Excute1: 3
Exclusive1: 4
Se a palavra -chave sincronizada for removida, os dois métodos serão executados simultaneamente e não terão influência mútua.
Mas, como escrito no exemplo da sub -rotina, mesmo dois métodos:
O resultado da execução é sempre a saída de um encadeamento e, em seguida, a execução de outro thread.
ilustrar:
Se um objeto possui vários métodos sincronizados e um thread inseriu um método sincronizado em um determinado momento, outros threads não poderão acessar nenhum método sincronizado do objeto antes que o método seja executado.
para concluir:
Quando a palavra -chave sincronizada modifica um método, o método é chamado de método de sincronização.
Cada objeto em Java tem um bloqueio ou um monitor. Quando um thread acessa o método sincronizado de um objeto, o objeto é bloqueado e nenhum outro encadeamento pode acessar o método sincronizado do objeto (aqui se refere a todos os métodos de sincronização, não apenas o mesmo método). Não é até o encadeamento anterior concluir o método de execução (ou lança uma exceção), a trava do objeto é liberada, para que outros threads possam acessar o método sincronizado do objeto novamente.
Observe que o objeto está bloqueado neste momento. Se for um objeto diferente, não há relação de restrição entre os objetos.
Ao tentar construir um segundo objeto de encadeamento no código, um novo objeto de exemplo é passado, não há restrição entre a execução dos dois threads.
3. Método de sincronização estática
Quando um método modificado de palavra-chave sincronizado também é modificado pela estática, foi dito antes que um método de sincronização não estático bloqueie o objeto, mas o método estático não pertence ao objeto, mas a uma classe e trava o objeto de classe da classe em que esse método está localizado.
public class ThreadTest {public static void main (string [] args) {exemplo exemplo = new Exempli (); Exemplo de exemplo2 = novo exemplo (); Thread t1 = new Thread1 (exemplo); Thread T2 = novo Thread2 (Exemplo2); t1.start (); t2.start (); }} Exemplo de classe {public sincronizado estático void escape () {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (interruptedException e) {e.printStackTrace (); } System.out.println ("escutas:" + i); }} public sincronizado estático void exaustor1 () {for (int i = 0; i <5; ++ i) {tente {thread.sleep (1000); } catch (interruptedException e) {e.printStackTrace (); } System.out.println ("Excute1:" + i); }}} classe Thread1 estende o thread {Exemplo privado Exemplo; public Thread1 (exemplo de exemplo) {this.example = exemplo; } @Override public void run () {exemplo.excute (); }} classe Thread2 estende o thread {Exemplo privado Exemplo; public Thread2 (exemplo de exemplo) {this.example = exemplo; } @Override public void run () {exemplo.excute1 (); }}Os resultados da execução são os seguintes
Excute: 0
EXCUTA: 1
EXCUTA: 2
EXCUTA: 3
EXCUTA: 4
Excute1: 0
Excute1: 1
Excute1: 2
Excute1: 3
Exclusive1: 4
Se não houver modificador estático e dois threads passarem objetos diferentes, eles serão executados simultaneamente ao mesmo tempo.
Portanto, se for um método estático (Execute () e Execute2 () ambos possuem palavras -chave estáticas adicionadas), mesmo que diferentes objetos de exemplo sejam passados para dois threads, os dois threads ainda são restringidos um pelo outro. É preciso ser executado primeiro e depois o próximo.
para concluir:
Se um método sincronizado for estático, quando um thread acessa o método, ele não bloqueia o objeto em que o método sincronizado está localizado, mas o objeto de classe correspondente à classe em que o método sincronizado está localizado. Em Java, não importa quantos objetos uma classe tenha, esses objetos corresponderão a um objeto de classe exclusivo. Portanto, quando um encadeamento acessa dois métodos estáticos e sincronizados de dois objetos da mesma classe, sua ordem de execução também é seqüencial, ou seja, um thread executa o método primeiro e o outro thread inicia após a execução ser concluída.
4. Bloco sincronizado
sincronizado (objeto)
{
}
Isso significa que o encadeamento bloqueará o objeto quando for executado. (Observe que este objeto pode ser um objeto de qualquer classe ou você pode usar essa palavra -chave).
Dessa forma, você pode especificar o objeto bloqueado sozinho.
public class ThreadTest {public static void main (string [] args) {exemplo exemplo = new Exempli (); Thread t1 = new Thread1 (exemplo); Thread t2 = new Thread2 (exemplo); t1.start (); t2.start (); }} classe Exemplo {public void exain () {Synchronized (this) {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (interruptedException e) {e.printStackTrace (); } System.out.println ("escutas:" + i); }}} public void exaustor1 () {sincronizado (this) {for (int i = 0; i <5; ++ i) {tente {thread.sleep (1000); } catch (interruptedException e) {e.printStackTrace (); } System.out.println ("Excute1:" + i); }}}}}} classe Thread1 estende o thread {Exemplo privado Exemplo; public Thread1 (exemplo de exemplo) {this.example = exemplo; } @Override public void run () {exemplo.excute (); }} classe Thread2 estende o thread {Exemplo privado Exemplo; public Thread2 (exemplo de exemplo) {this.example = exemplo; } @Override public void run () {exemplo.excute1 (); }}Os resultados da execução são os seguintes
Excute: 0
EXCUTA: 1
EXCUTA: 2
EXCUTA: 3
EXCUTA: 4
Excute1: 0
Excute1: 1
Excute1: 2
Excute1: 3
Exclusive1: 4
O efeito alcançado pelo Exemplo do Programa 4 é o mesmo do programa de exemplo 2. Ambos os threads são executados em sequência, em vez de simultaneamente. Quando um thread é executado, o objeto é bloqueado e o outro thread não pode executar o bloco correspondente.
O método sincronizado é realmente equivalente a envolver todas as declarações no método com um bloco sincronizado e, em seguida, passar essa palavra -chave nos colchetes do bloco sincronizado. Obviamente, se for um método estático, o objeto de classe precisa ser bloqueado.
Talvez apenas algumas linhas de código em um método envolvam problemas de sincronização de encadeamentos; portanto, o bloco sincronizado controla o acesso de vários threads de maneira mais granular do que o método sincronizado. Somente o conteúdo no bloco sincronizado não pode ser acessado por vários threads ao mesmo tempo, e outras instruções no método ainda podem ser acessadas por vários threads ao mesmo tempo (incluindo o bloco sincronizado).
para concluir:
O método sincronizado é um controle simultâneo de grão grosso. Em um certo momento, apenas um thread pode executar o método sincronizado;
O bloco sincronizado é um controle de simultaneidade de granulação fina, que apenas sincroniza o código no bloco. Outros códigos localizados no método e outros blocos sincronizados podem ser acessados por vários threads ao mesmo tempo.
O exposto acima é sobre o método de sincronização de bloco sincronizado da programação multi-thread Java. Espero que seja útil para o aprendizado de todos.