| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/01/2010 09:50:50
|
laudenpower
JavaEvangelist
![[Avatar]](/images/avatar/090d1f9732c52fc3770cba691cff7d11.jpg)
Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline
|
Olá a todos, bom tenho um programa que atua em cima de uma variável incrementando ela, porém isso é feito em uma thread separada. Em outra parte (outra thread) do programa eu decremento ela, gostaria de saber qual o efeito dessas duas threads acessarem essa variável ao mesmo tempo. Nesse caso é possível acontecer de ele realizar apenas o incremento descartando a operação de decremento?
|
Enquanto cultivares teu saber, nada tens a temer!
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999 |
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/01/2010 10:02:51
|
entanglement
GUJ Hacker
Membro desde: 26/09/2009 09:18:56
Mensagens: 5750
Offline
|
O incremento e o decremento de uma variável int, char, short ou byte é garantido ser atômico. Isso porque são realizados usando-se uma única instrução do processador.
O incremento e o decremento de uma variável long (64 bits) não é garantido ser atômico, portanto você poderia ter uma situação em que a variável é parcialmente atualizada (porque ela é acessada em 2 acessos à memória, se usar uma JVM de 32 bits) e os dados ficarem incoerentes.
Em uma JVM de 64 bits isso provavelmente não deve ocorrer, mas isso não está especificado na especificação da JVM.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/01/2010 10:04:31
|
entanglement
GUJ Hacker
Membro desde: 26/09/2009 09:18:56
Mensagens: 5750
Offline
|
Entretanto, você DEVE indicar o atributo "volatile" a essa variável acessada por 2 threads.
Isso é porque as threads podem estar em processadores diferentes e devido ao design do cache pode ser que a alteração de uma variável, se não for marcada com "volatile", não seja reconhecida de um processador para o outro.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/01/2010 10:06:14
|
entanglement
GUJ Hacker
Membro desde: 26/09/2009 09:18:56
Mensagens: 5750
Offline
|
http://java.sun.com/javase/6/docs/api/java/util/concurrent/atomic/package-summary.html para detalhes sobre acesso simultâneo para incremento e decremento. (É mais seguro usar java.util.concurrent.atomic.AtomicInteger que uma variável volatile int, já que as instruções do sistema operacional que forçam que ambas as threads enxergem o mesmo valor para a variável sejam executadas.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/01/2010 10:06:36
|
laudenpower
JavaEvangelist
![[Avatar]](/images/avatar/090d1f9732c52fc3770cba691cff7d11.jpg)
Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline
|
Desde já gostaria de agradecer sua resposta e me colocar a disposição para ajuda-lo também (caso precisares ), nesse caso é uma variável int, logo então não existe forma de alguma operação deixar de ser executada. Apenas para esclarecer melhor, o programa roda em apenas um processador e está sendo usado a jre1.6.
This message was edited 1 time. Last update was at 18/01/2010 10:08:19
|
Enquanto cultivares teu saber, nada tens a temer!
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/01/2010 10:09:39
|
ViniGodoy
Moderador
![[Avatar]](/images/avatar/1921493b5362e63fbe8983f4bd54157d.png)
Membro desde: 11/12/2006 08:22:01
Mensagens: 20578
Localização: Curitiba/PR
Offline
|
entanglement wrote:Entretanto, você DEVE indicar o atributo "volatile" a essa variável acessada por 2 threads.
Outra opção seria deixar o acesso a essa variável num bloco sincronizado. Mas eu também optaria pelo volatile, caso você esteja apenas fazendo essas continhas de incremento e decremento.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/01/2010 10:18:26
|
laudenpower
JavaEvangelist
![[Avatar]](/images/avatar/090d1f9732c52fc3770cba691cff7d11.jpg)
Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline
|
Tipo tava analizando a classe AtomicInteger mas acho que seria usar um canhão acelerador de particulas para matar um pernilongo.
Acredito que o volatile já seja suficiente, mas apenas esclarecendo, sem o volatile eu corro o risco de perder uma operação (exemplo um decremento)?
|
Enquanto cultivares teu saber, nada tens a temer!
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/01/2010 10:34:34
|
ViniGodoy
Moderador
![[Avatar]](/images/avatar/1921493b5362e63fbe8983f4bd54157d.png)
Membro desde: 11/12/2006 08:22:01
Mensagens: 20578
Localização: Curitiba/PR
Offline
|
Sim. Sem volatile você pode estar olhando para o cache local das threads. Assim, um decremento numa thread pode não ser visto na outra. E quando a outra atualizar o valor, irá atualizar para um valor errado. O volatile pede para o Java não usar esse cache.
|
@ViniGodoy - Lattes
Tem dúvidas de Java? Poste no fórum! Não respondo dúvidas de java via MP!
Ponto V! - Desenvolvimento de Jogos Profissional - @Pontov - Facebook
Projeto Towel - Swing de uma forma inteligente (Novo lar do ObjectTableModel e do Auto-Filtro).
Ei... você está usando DefaultTableModel no seu projeto??
Não faça isso! Veja: http://www.guj.com.br/posts/list/15/199067.java#1001295 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/01/2010 11:00:04
|
marcobiscaro2112
JWizard
Membro desde: 01/12/2008 11:56:04
Mensagens: 2408
Localização: São Paulo - SP
Offline
|
entanglement wrote:Isso porque são realizados usando-se uma única instrução do processador.
Isso me gerou uma dúvida. Um incremento simples:
Gera somente uma instrução de bytecode:
Mas... (sempre tem um mas) segundo o capítulo de concorrência do tutorial da Sun:
http://java.sun.com/docs/books/tutorial/essential/concurrency/interfere.html wrote:
However, even simple statements can translate to multiple steps by the virtual machine. We won't examine the specific steps the virtual machine takes ? it is enough to know that the single expression c++ can be decomposed into three steps:
1. Retrieve the current value of c.
2. Increment the retrieved value by 1.
3. Store the incremented value back in c.
Que é apenas uma operação unária no Java eu sei. Que gera apenas um comando de bytecode também sei.
Mas afinal, é apenas uma instrução para o processador ou não?
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/01/2010 11:08:41
|
laudenpower
JavaEvangelist
![[Avatar]](/images/avatar/090d1f9732c52fc3770cba691cff7d11.jpg)
Membro desde: 28/12/2008 21:00:08
Mensagens: 349
Offline
|
Então nesse caso se uma thread estiver incrementando a variável, a outra ficará em espera para poder acessar o valor?
|
Enquanto cultivares teu saber, nada tens a temer!
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/01/2010 11:21:44
|
ViniGodoy
Moderador
![[Avatar]](/images/avatar/1921493b5362e63fbe8983f4bd54157d.png)
Membro desde: 11/12/2006 08:22:01
Mensagens: 20578
Localização: Curitiba/PR
Offline
|
laudenpower wrote:Então nesse caso se uma thread estiver incrementando a variável, a outra ficará em espera para poder acessar o valor?
No caso do synchronized há espera. No caso do volatile, não. Até por isso o volatile só garante thread safety caso sua variável só sofra operações atômicas. Como leitura do valor e um update simples (como um set direto ou incremento/decremento).
This message was edited 1 time. Last update was at 18/01/2010 11:22:59
|
@ViniGodoy - Lattes
Tem dúvidas de Java? Poste no fórum! Não respondo dúvidas de java via MP!
Ponto V! - Desenvolvimento de Jogos Profissional - @Pontov - Facebook
Projeto Towel - Swing de uma forma inteligente (Novo lar do ObjectTableModel e do Auto-Filtro).
Ei... você está usando DefaultTableModel no seu projeto??
Não faça isso! Veja: http://www.guj.com.br/posts/list/15/199067.java#1001295 |
|
|
 |
|
|