O método de sincronização mais básico do Java é usar a palavra -chave sincronizada para controlar o acesso simultâneo de um método. Todo método declarado com a palavra -chave sincronizada é uma seção crítica. Em Java, apenas uma das seções críticas do mesmo objeto pode ser acessada ao mesmo tempo.
Métodos estáticos têm comportamentos diferentes. Um método estático declarado com a palavra-chave sincronizado só pode ser acessado por um thread de execução, mas outros threads podem acessar o método sincronizado não estático desse objeto. Isso deve ser muito cauteloso, porque dois threads podem acessar dois métodos sincronizados diferentes de um objeto ao mesmo tempo, ou seja, um dos quais é um método sincronizado estático e o outro é um método sincronizado não estático. Se ambos os métodos alterarem os mesmos dados, ocorrerá um erro inconsistente.
A sintaxe do bloco sincronizado é o seguinte:
public void Method () {Synchronized (Expression) {}} Existem dois usos da palavra -chave sincronizada. Um é usado apenas na definição de métodos e o outro é o bloco sincronizado. Não podemos apenas usar sincronizados para sincronizar uma variável de objeto, mas você também pode usar o sincronizado para sincronizar métodos estáticos e métodos não estáticos na classe.
O primeiro: sincronização de métodos não estáticos
A partir da sintaxe relacionada a Java, podemos saber que o uso da palavra-chave sincronizada para definir um método bloqueará os métodos estáticos e os métodos não estáticos definidos pela palavra-chave Synchroniezd na classe, mas isso é um pouco difícil de entender. Se você deseja sincronizar blocos para alcançar esse efeito, não é difícil entender por que esse efeito é produzido. Se você usar sincronizado para bloquear todos os métodos não estáticos sincronizados na classe, você só precisará usá-lo como parâmetro do bloco sincronizado para passar para o bloco sincronizado. O código é o seguinte:
public class Test {public void method1 () {Synchronized (this) {}} public sincronizada void method2 () {}} public class Test {public void Method1 () {Synchronized (this) {}} public sincronizada void Method2 () {}} No código acima, o método1 usa o bloco sincronizado e o método Method2 usa a palavra -chave sincronizada para definir o método. Se você usar a mesma instância de teste, desde que um desses dois métodos esteja sendo executado, os outros métodos serão bloqueados porque eles não obtiveram o bloqueio de sincronização. Além de usar isso como parâmetro do bloco sincronizado, você também pode usar o teste.
Ao usar blocos sincronizados nas classes internas, isso representa apenas classes internas e não tem nada a ver com classes externas (Exterterclass). No entanto, métodos não estáticos em classes internas e métodos não estáticos nas classes externas também podem ser sincronizadas. Se você adicionar um método de método3 à classe interna, também poderá sincronizar com os dois métodos em teste, o código é o seguinte:
public class Test {class InnerClass {public void Method3 () {Synchronized (test.this) {}}} public class Test {class InnerClass {public void Method3 () {Synchronized (test.This) {}}}}}}}} O método3 Método3 de Innerclass acima e os métodos de teste Method1 e Method2 podem ter apenas um método executado ao mesmo tempo.
Se o bloco sincronizado é executado corretamente ou o bloco sincronizado é excitado devido a uma exceção devido a um erro do programa, a trava de sincronização mantida pelo bloco sincronizada atual será liberada automaticamente. Portanto, você não precisa se preocupar com o bloqueio de sincronização ao usar o bloco sincronizado.
2. Sincronização de métodos estáticos
Como as instâncias do objeto não são necessariamente criadas ao chamar métodos estáticos, isso não pode ser usado para sincronizar métodos estáticos, mas deve usar objetos de classe para sincronizar métodos estáticos. O código é o seguinte:
public class Test {public static void method1 () {Synchronized (test.class) {}} public static sincronizado void method2 () {}} public class Test {public static void method1 () {synchronized (test.class) {}}} public static static static synchron Method2 () (test.class) {}}} public static static static synch2s2 () {Synchronized (Test.class) {}}} public static static synch2s2 () {Synchronized (test.class) {}}} public static static static synch2s2)Ao sincronizar métodos estáticos, você pode usar a classe de campo estático da classe para obter o objeto de classe. No exemplo acima, existe apenas uma execução do método dos métodos Method1 e Method2. Além de usar o campo de classe, você também pode obter o objeto de classe através do método getClass () da instância. O código é o seguinte:
Public class Test {Teste estático público; public test () {test = this; } public static void method1 () {sincronizado (test.getclass ()) {}} public class Test {public static test teste; public test () {test = this; } public static void method1 () {synchronized (test.getclass ()) {}}}
No código acima, obtemos uma instância de teste através de um objeto estático público e obtemos um objeto de classe através do método getClass desta instância (observe que todas as instâncias de uma classe são obtidas através do método getClass). Também podemos sincronizar métodos estáticos de diferentes classes através da classe, o código é o seguinte:
public class Test1 {public static void method1 () {Synchronized (test.class) {}}} public class Test1 {public static void method1 () {synchronized (test.class) {}}}
Nota: Quando os blocos sincronizados são usados para sincronizar métodos, métodos não estáticos podem ser sincronizados através disso, enquanto os métodos estáticos devem ser sincronizados usando objetos de classe, mas métodos não estáticos também podem ser sincronizados usando a classe. No entanto, isso não pode ser usado em métodos estáticos para sincronizar métodos não estáticos. Isso precisa receber atenção ao usar blocos sincronizados.
Observação
A palavra -chave sincronizada degradará o desempenho do aplicativo e, portanto, só pode ser usada em métodos que exigem modificação de dados compartilhados em cenários simultâneos. Se vários threads acessarem o mesmo método sincronizado, apenas um thread poderá acessá -lo e os outros threads esperarão. Se a declaração do método não usar a palavra -chave sincronizada, todos os threads poderão executar o método ao mesmo tempo, reduzindo assim o tempo total de execução. Se você é conhecido por ser chamado por mais de um thread, não precisará declará -lo usando a palavra -chave sincronizada.
Os métodos declarados sincronizados podem ser chamados recursivamente. Quando um thread acessa o método de sincronização de um objeto, ele também pode chamar outros métodos de sincronização do objeto, incluindo o método de execução, sem precisar obter acesso ao método novamente.
Podemos proteger o acesso a blocos de código (em vez de todo o método) através da palavra -chave sincronizada. A palavra -chave sincronizada deve ser usada assim: o restante do método permanece fora do bloco de código sincronizado para melhor desempenho. O acesso à seção crítica (ou seja, blocos de código que só podem ser acessados por um thread ao mesmo tempo) devem ser o mais curtos possível. Por exemplo, na operação de obter o número de pessoas em um edifício, usamos apenas a palavra -chave sincronizada para proteger as instruções para atualizar o número de pessoas e fazer com que outras operações não usem dados compartilhados. Ao usar palavras -chave sincronizadas dessa maneira, a referência do objeto deve ser usada como um parâmetro recebido. Apenas um thread pode acessar esse código sincronizado ao mesmo tempo. De um modo geral, usamos essa palavra -chave para nos referir ao objeto ao qual o método executado pertence:
Sincronizado (this) {// Java Code}