[Prévia] [Próxima] [Prévia por assunto] [Próxima por assunto]
[Índice cronológico]
[Índice de assunto]
Re: [reverbel-mac438] Bounded buffer com notifyAll: o notifyAll é mesmo necessário?
- Subject: Re: [reverbel-mac438] Bounded buffer com notifyAll: o notifyAll é mesmo necessário?
- From: Francisco Reverbel <reverbel@xxxxxxxxxx>
- Date: Sat, 03 Jun 2006 16:29:17 -0300
Um problema com a classe
http://www.ime.usp.br/~reverbel/mac438-06/java-src/BoundedBufferWithStateTracking2.java
é o da perda de um notify, que pode (muitíssimo raramente) ocorrer caso
uma thread que esteja num wait seja simultaneamente interrompida
(através de uma chamada ao método interrupt() na própria thread) e
notificada (através de uma chamada ao método notify() no objeto usado
como "variável de condição").
Desconsiderem esse problema, supondo que ninguém nunca chamar
interrupt() nas threads que usam o bounded buffer, ou, alternativamente,
modifiquem a classe acima, fazendo-a apanhar InterruptException e dar um
notify() adicional para compensar a possível (embora improvável) perda
de uma notificação. Esta é a classe modificada:
http://www.ime.usp.br/~reverbel/mac438-06/java-src/BoundedBufferWithStateTracking3.java
A questão importante é: a classe BoundedBufferWithStateTracking3 está
correta ou não? Ou, equivalentemente, supondo-se que as threads usuárias
do bounded buffer nunca sejam alvo de chamadas interrupt(), a classe
BoundedBufferWithStateTracking2 está correta ou não?
Reverbel
On Sat, 2006-06-03 at 15:49 -0300, Francisco Reverbel wrote:
> Na última aula vimos uma implementação de bounded buffer que usava
> notifyAll (e portanto tinha os problemas de desempenho decorrentes do
> uso de notifyAll) e depois escrevemos uma segunda implementação de
> bounded buffer, que não usava notifyAll mas era completamente diferente
> da primeira.
>
> Depois da aula um aluno me fez uma pergunta muito relevante: a gente
> precisava mesmo ter tido tanto trabalho só para se livrar do notifyAll?
> Se simplesmente trocássemos as duas chamadas a notifyAll na primeira
> implementação por chamadas a notify, a classe resultante não estaria
> correta?
>
> Para referência, esta é a implementação de bounded buffer com notifyAll:
> http://www.ime.usp.br/~reverbel/mac438-06/java-src/BoundedBufferWithStateTracking.java
>
> No caso geral, não dá nem para pensar em sair trocando chamadas a
> notifyAll por chamadas a notify. Neste caso particular, entretanto, isso
> parece fazer sentido. Apesar do conjunto de espera manipulado pelas
> operações wait/notify/notifyAll ser usado por duas condições distintas
> ("há dado no buffer" e "há espaço no buffer"), a espera por essas
> condições não deve ser simultânea (ou se espera por dado, ou se espera
> por espaço). Já que se está esperando por dado ou por espaço, por que
> não usar um notify simples em vez de notifyAll? Dessa forma se acordaria
> apenas uma das threads esperando por dado (no caso da notificação gerada
> pelo método put) ou uma das threads que estão esperando por espaço (no
> caso da notificação gerada pelo método take)?
>
> O raciocínio acima é válido ou não? Em outras palavras, é ou não correta
> a classe
>
> http://www.ime.usp.br/~reverbel/mac438-06/java-src/BoundedBufferWithStateTracking2.java
>
> obtida a partir da primeira implementação de bounded buffer pela simples
> troca de notifyAll por notify?
>
> Discutiremos essa questão na próxima aula. (Não percam essa aula, pois a
> questão é importante e, até onde eu sei, não é tratada em livro algum.)
> O assunto mais geral subjacente é o do compartilhamento de um mesmo
> conjunto de espera entre condições logicamente distintas. Para a nossa
> discussão ser mais interessante e produtiva, gostaria que todos vocês
> pensassem na questão antes da aula e tivessem sua própria resposta.
>
> Pensem bem... A resposta não é óbvia!
>
> Reverbel
>
>