Há uma pergunta simples e estúpida que me incomoda e traz vários argumentos em minha mente. Quero tirar todas as dúvidas sobre as questões abaixo.
class Clstest{
public static String testStaticMethod(String inFileStr) {
// section 0
// section 1
// do something with inFileStr
// section 2
// section 3
return inFileStr;
}
}
Vamos supor que cinco threads estão executando uma chamada para Clstest.testStaticMethod("arg-n")
ao mesmo tempo.
Thread 1 chama Clstest.testStaticMethod("arg-1")
.
Quando o thread 1 está na seção 1, o thread 2 chama Clstest.testStaticMethod("arg-2")
.
Então, o que acontecerá com o Tópico 1? Ele irá para o estado de suspensão?
Quando o Thread 1 tiver a chance, ele retomará a execução da seção 1 onde foi pausado?
Como isso acontece quando há um Clstest.testStaticMethod
e o mesmo Clstest.testStaticMethod
é compartilhado entre todos os cinco tópicos?
Existe alguma possibilidade de trocar o inFileStr
enviado por vários threads?
fonte
Respostas:
A resposta de Hans Passant é boa. Mas pensei em tentar explicar em um nível um pouco mais simples para qualquer pessoa que se deparar com isso e for novato em Java. Aqui vai ..
A memória em java é dividida em dois tipos - heap e pilhas. O heap é onde todos os objetos vivem e as pilhas são onde os threads fazem seu trabalho. Cada thread tem sua própria pilha e não podem acessar as pilhas umas das outras. Cada thread também tem um ponteiro para o código que aponta para o trecho de código que eles estão executando no momento.
Quando um thread começa a executar um novo método, ele salva os argumentos e as variáveis locais desse método em sua própria pilha. Alguns desses valores podem ser ponteiros para objetos no heap. Se duas threads estiverem executando o mesmo método ao mesmo tempo, ambas terão seus ponteiros de código apontando para esse método e terão suas próprias cópias de argumentos e variáveis locais em suas pilhas. Eles só interferirão uns com os outros se as coisas em suas pilhas apontarem para os mesmos objetos na pilha. Nesse caso, todo tipo de coisa pode acontecer. Mas, como Hans aponta, Strings são imutáveis (não podem ser alteradas), então estamos seguros se este for o único objeto sendo "compartilhado".
Muitos threads podem estar executando o mesmo método. Eles podem não estar sendo executados ao mesmo tempo - isso depende de quantos núcleos você tem em sua máquina, pois a JVM mapeia os encadeamentos Java para os encadeamentos do SO, que são planejados nos encadeamentos de hardware. Portanto, você tem pouco controle sobre a maneira como esses threads se intercalam sem usar mecanismos de sincronização complexos .
Observe que dormir é algo que um thread faz a si mesmo.
fonte
Não, a execução de um encadeamento não afeta outros encadeamentos, desde que eles não sejam sincronizados intencionalmente entre si. Se você tiver mais de um núcleo de processador, todas as máquinas recentes têm, esses threads provavelmente serão executados exatamente ao mesmo tempo. Isso se torna um pouco menos provável quando você inicia 5 threads, pois sua máquina pode não ter núcleos suficientes. O sistema operacional é forçado a escolher entre eles, dando a cada um deles algum tempo para serem executados. O trabalho do planejador de thread. Um encadeamento não estará em um estado de "suspensão", ele simplesmente será pausado e aguardará o agendador do encadeamento para dar uma chance de execução. Ele continuará onde foi interrompido pelo planejador.
Não existe essa possibilidade, as threads têm sua própria pilha, portanto, qualquer argumento de método e variável local será exclusivo para cada thread. Usando umAlém disso, o string garante que essas threads não interfiram umas com as outras, pois as strings são imutáveis.
Essa garantia não existe se o argumento for uma referência a outro tipo de objeto mutável. Ou se o próprio método usa variáveis que são estáticas ou referências a objetos no heap. A sincronização é necessária quando um thread modifica o objeto e outro thread o lê. A palavra-chave lock na linguagem C # é a maneira padrão de implementar a sincronização necessária. O fato de o método ser estático não significa que essa sincronização nunca seja necessária. Menos provável, pois você não precisa se preocupar com threads acessando o mesmo objeto (compartilhando isso ).
fonte