A palavra-chave sincronizada tem dois usos. A primeira é utilizá-lo diretamente na definição do método conforme apresentado no artigo "Usando a palavra-chave Synchronized para sincronizar métodos de classe". Outro tipo é o bloco sincronizado. Não podemos apenas sincronizar uma variável de objeto através de blocos sincronizados. Você também pode usar blocos sincronizados para sincronizar métodos estáticos e não estáticos em uma classe.
A sintaxe do bloco sincronizado é a seguinte:
Copie o código do código da seguinte forma:
método vazio público()
{
… …
sincronizado (expressão)
{
… …
}
}
1. Sincronização de métodos de classe não estáticos
Do artigo "Usando a palavra-chave Synchronized para sincronizar métodos de classe", sabemos que usar a palavra-chave sincronizada para definir métodos bloqueará todos os métodos estáticos ou não estáticos definidos usando a palavra-chave sincronizada na classe, mas isso não é fácil de entender. Se você usar blocos sincronizados para obter o mesmo efeito, não será difícil entender por que esse efeito ocorre. Se você quiser usar um bloco sincronizado para bloquear todos os métodos não estáticos sincronizados em uma classe, você precisa usar isso como parâmetro do bloco sincronizado e passá-lo para o país do bloco sincronizado.
Sincronize métodos não estáticos por meio de blocos sincronizados
Copie o código do código da seguinte forma:
classe pública SyncBlock
{
método de vazio público1()
{
sincronizado(this) // Equivalente a usar a palavra-chave sincronizada no método method1
{
… …
}
}
método de vazio público2()
{
sincronizado(this) // Equivalente a usar a palavra-chave sincronizada para o método method2
{
… …
}
}
método de void sincronizado público3()
{
… …
}
}
No código acima, blocos sincronizados são usados nos métodos método1 e método2. O método method3 na linha 017 ainda usa a palavra-chave sincronizada para definir o método. Ao usar a mesma instância da classe SyncBlock, enquanto um dos três métodos estiver em execução, os outros dois métodos serão bloqueados porque o bloqueio de sincronização não foi obtido. Para obter o mesmo efeito da palavra-chave sincronizada ao usar o bloco sincronizado, todo o código deve ser escrito no bloco sincronizado, caso contrário, todo o código no método atual não será sincronizado com outros métodos.
Além de usar this como parâmetro do bloco sincronizado, você também pode usar SyncBlock.this como parâmetro do bloco sincronizado para obter o mesmo efeito.
Ao usar o bloco sincronizado no método da classe interna (InnerClass), isso representa apenas a classe interna e não tem nada a ver com a classe externa (OuterClass). Mas os métodos não estáticos da classe interna podem ser sincronizados com os métodos não estáticos da classe externa. Por exemplo, adicione um método method4 à classe interna InnerClass e sincronize o método method4 com os três métodos de SyncBlock.
Sincronize métodos não estáticos da classe interna com métodos não estáticos da classe externa
Copie o código do código da seguinte forma:
classe pública SyncBlock
{
… …
classeInnerClass
{
método de vazio público4()
{
sincronizado (SyncBlock.this)
{
… …
}
}
}
… …
}
Na nova versão da classe SyncBlock acima, o método 4 da classe InnerClass é sincronizado com os outros três métodos da classe SyncBlock. Portanto, apenas um método dos quatro métodos método1, método2, método3 e método4 pode ser executado. ao mesmo tempo.
Quer o bloco sincronizado seja executado normalmente ou saia do bloco sincronizado de forma anormal devido a um erro de programa, o bloqueio de sincronização mantido pelo bloco sincronizado atual será automaticamente liberado. Portanto, você não precisa se preocupar com a liberação de bloqueios de sincronização ao usar blocos sincronizados.
2. Sincronização de métodos de classe estática
Porque ao chamar um método estático, a instância do objeto não é necessariamente criada. Portanto, você não pode usar isso para sincronizar métodos estáticos, mas deve usar objetos Class para sincronizar métodos estáticos. O código é o seguinte:
Sincronize métodos estáticos por meio de blocos sincronizados
Copie o código do código da seguinte forma:
classe pública StaticSyncBlock
{
método de void estático público1()
{
sincronizado (StaticSyncBlock.class)
{
… …
}
}
método público estático sincronizado void2()
{
… …
}
}
Ao sincronizar métodos estáticos, você pode usar a classe de campo estático da classe para obter o objeto Class. No exemplo acima, apenas um método de método1 e método2 pode ser executado ao mesmo tempo. Além de usar o campo class para obter o objeto Class, você também pode usar o método getClass da instância para obter o objeto Class. O código no exemplo acima pode ser modificado da seguinte forma:
Use o método getClass para obter o objeto Class
Copie o código do código da seguinte forma:
classe pública StaticSyncBlock
{
instância pública estática de StaticSyncBlock;
public StaticSyncBlock()
{
instância = isto;
}
método de void estático público1()
{
sincronizado(instance.getClass())
{
}
}
}
No código acima, uma instância da classe StaticSyncBlock é obtida por meio de uma instância estática pública, e o objeto Class é obtido por meio do método getClass desta instância (todas as instâncias de uma classe obtêm o mesmo objeto Class por meio do método getClass, portanto, chamar qualquer método getClass de uma instância pode ser usado). Também podemos sincronizar métodos estáticos de diferentes classes por meio de objetos Class, como o método estático da classe Test e os dois métodos estáticos da classe StaticSyncBlock.
O método method da classe Test é sincronizado com os métodos method1 e method2 da classe StaticSyncBlock.
Copie o código do código da seguinte forma:
Teste de classe pública
{
método vazio estático público ()
{
sincronizado (StaticSyncBlock.class)
{
}
}
}
Nota: Ao usar métodos de classe de sincronização de blocos sincronizados, os métodos não estáticos podem usar isso para sincronizar, enquanto os métodos estáticos devem usar o objeto Class para sincronizar. Eles não afetam um ao outro. Claro, você também pode usar objetos Class em métodos não estáticos para sincronizar métodos estáticos. Mas isso não pode ser usado em métodos estáticos para sincronizar métodos não estáticos. Isso deve ser observado ao usar métodos de classe de sincronização de blocos sincronizados.