[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?



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
> 
>