Acesso simultâneo (duas threads) a uma variável  XML
Índice dos Fóruns » Java Avançado
Autor Mensagem
laudenpower
JavaEvangelist
[Avatar]

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
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.
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.
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.
laudenpower
JavaEvangelist
[Avatar]

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
ViniGodoy
Moderador
[Avatar]

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.
[WWW]
laudenpower
JavaEvangelist
[Avatar]

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
ViniGodoy
Moderador
[Avatar]

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
[WWW]
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?
[Email] [WWW] [MSN]
laudenpower
JavaEvangelist
[Avatar]

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
ViniGodoy
Moderador
[Avatar]

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
[WWW]
 
Índice dos Fóruns » Java Avançado
Ir para:   
Powered by JForum 2.1.8 © JForum Team