Eu queria saber se você tem um método estático que não é sincronizado, mas não modifica nenhuma variável estática, é seguro para threads? E se o método criar variáveis locais dentro dele? Por exemplo, o código a seguir é seguro para threads?
public static String[] makeStringArray( String a, String b ){
return new String[]{ a, b };
}
Portanto, se eu tiver dois threads chamando esse método de forma contínua e simultânea, um com cães (digamos "great dane" e "bull dog") e outro com gatos (digamos "persa" e "siamês") sempre receberei gatos e cães na mesma matriz? Ou os cães e gatos nunca estarão dentro da mesma invocação do método ao mesmo tempo?
Respostas:
Esse método é 100% seguro para threads, seria mesmo se não fosse
static
. O problema com a segurança de threads surge quando você precisa compartilhar dados entre threads - você deve cuidar da atomicidade, visibilidade etc.Este método opera apenas em parâmetros, que residem na pilha e fazem referência a objetos imutáveis na pilha. A pilha é inerentemente local ao encadeamento , portanto, nenhum compartilhamento de dados ocorre.
Objetos imutáveis (
String
neste caso) também são seguros para threads porque, uma vez criados, não podem ser alterados e todos os threads veem o mesmo valor. Por outro lado, se o método estivesse aceitando (mutável),Date
você poderia ter tido um problema. Dois threads podem modificar simultaneamente a mesma instância do objeto, causando condições de corrida e problemas de visibilidade.fonte
Um método só pode ser inseguro de thread quando altera algum estado compartilhado. Se é estático ou não, é irrelevante.
fonte
A função é perfeitamente segura para threads.
Se você pensar sobre isso ... assuma o que aconteceria se isso fosse diferente. Todas as funções usuais teriam problemas de encadeamento se não fossem sincronizadas, portanto, todas as funções de API no JDK precisariam ser sincronizadas, pois elas poderiam ser chamadas por vários encadeamentos. E como na maioria das vezes o aplicativo usa alguma API, aplicativos multithread seriam efetivamente impossíveis.
Isso é ridículo demais para pensar sobre isso, então, só para você: Os métodos não são seguros para threads, se houver uma razão clara para a ocorrência de problemas. Tente sempre pensar no que se houvesse vários threads na minha função e se você tivesse um depurador de etapas e um passo após o outro avançasse o primeiro ... depois o segundo thread ... talvez o segundo novamente ... haveria problemas? Se você encontrar um, não é um thread seguro.
Esteja ciente de que a maioria das classes Java 1.5 Collection não é segura, exceto aquelas onde declaradas, como ConcurrentHashMap.
E se você realmente quiser mergulhar nisso, observe atentamente a palavra-chave volátil e TODOS os seus efeitos colaterais. Dê uma olhada na classe Semaphore () e Lock () e seus amigos em java.util.Concurrent. Leia todos os documentos da API nas classes. Também vale a pena aprender e satisfazer.
Desculpe por esta resposta excessivamente elaborada.
fonte
Use a
static
palavra-chave com métodos estáticos sincronizados para modificar dados estáticos compartilhados entre threads. Com astatic
palavra - chave, todos os threads criados disputarão uma única versão do método.O uso da
volatile
palavra - chave junto com os métodos de instância sincronizada garantirá que cada encadeamento tenha sua própria cópia dos dados compartilhados e nenhuma leitura / gravação vazará entre os encadeamentos.fonte
Objetos de sequência imutáveis são outro motivo para o cenário seguro para threads acima. Em vez disso, se objetos mutáveis forem usados (por exemplo, makeMutableArray ..), certamente a segurança do thread será interrompida.
fonte