Eu sei que o uso da synchronize
palavra - chave antes de um método traz sincronização para esse objeto. Ou seja, 2 threads executando a mesma instância do objeto serão sincronizados.
No entanto, como a sincronização está no nível do objeto, 2 threads executando instâncias diferentes do objeto não serão sincronizados. Se tivermos uma variável estática em uma classe Java chamada pelo método, gostaríamos que ela fosse sincronizada entre instâncias da classe. As duas instâncias estão em execução em 2 threads diferentes.
Podemos alcançar a sincronização da seguinte maneira?
public class Test
{
private static int count = 0;
private static final Object lock= new Object();
public synchronized void foo()
{
synchronized(lock)
{
count++;
}
}
}
É verdade que, uma vez que definimos um objeto lock
que é estático e estamos usando a palavra-chave synchronized
para esse bloqueio, a variável estática count
agora está sincronizada entre instâncias da classe Test
?
fonte
Respostas:
Existem várias maneiras de sincronizar o acesso a uma variável estática.
Use um método estático sincronizado. Isso sincroniza no objeto de classe.
Sincronize explicitamente no objeto de classe.
Sincronize em outro objeto estático.
O método 3 é o melhor em muitos casos, porque o objeto de bloqueio não é exposto fora da sua classe.
fonte
Test.class
e potencialmente estragar o seu dia. Além disso, a inicialização da classe é executada com um bloqueio na classe realizada; portanto, se você tiver inicializadores malucos, poderá se dar dores de cabeça.volatile
não ajudacount++
porque é uma sequência de leitura / modificação / gravação. Conforme observado em uma resposta diferente,java.util.concurrent.atomic.AtomicInteger
provavelmente é a escolha certa aqui.Test.class
.this
seria o bloqueio para métodos não estáticos sincronizadosSe você está simplesmente compartilhando um contador, considere usar um AtomicInteger ou outra classe adequada do pacote java.util.concurrent.atomic:
fonte
Sim, é verdade.
Se você criar duas instâncias da sua classe
Então t1.foo e t2.foo são sincronizados no mesmo objeto estático e, portanto, se bloqueiam.
fonte
Você pode sincronizar seu código pela classe. Isso seria mais simples.
Espero que você encontre esta resposta útil.
fonte
Test.class
e afetar o comportamento. É por isso que a sincronização ativadalock
pode ser preferida.Também podemos usar o ReentrantLock para obter a sincronização para variáveis estáticas.
fonte