Escolar Documentos
Profissional Documentos
Cultura Documentos
Threads Java-Sincronismo Primier
Threads Java-Sincronismo Primier
1 2
A necessidade de sincronizao .......................................................................................... 2 Sincronizao no Java.......................................................................................................... 2 2.1 A Keyword Syncronized................................................................................................. 2 2.2 Syncronized em mtodo static ......................................................................................... 3 2.3 Syncronized Statements .................................................................................................. 4 2.4 Herana ............................................................................................................................ 4 2.5 Mtodos wait() & notify() .................................................................................................. 4
1/4
1 A necessidade de sincronizao
Considere-se o exemplo de uma operao de depsito numa conta bancria. O Sr. Tobias vai realizar um depsito na sua conta conjunta com a esposa. No mesmo momento numa outra mquina ATM a Sr Tobias vai igualmente proceder a um depsito. Quando ambos se autenticam no sistema so lanadas threads, uma que cuidar das operaes do Sr. Tobias e outra que cuidar das operaes da Sr Tobias. Atenda-se seguinte sequncia possvel de operaes: Mquina do Sr.Tobias Saldo1=conta.getSaldo() Saldo1+=deposito1 Saldo2+=deposito2 Conta.setSaldo(Saldo1) Conta.setSaldo(Saldo2) Nesta situao s o deposito da Sr. Tobias tem efeito, perdendo-se o deposito do Sr. Tobias. Do exemplo anterior advm a necessidade de utilizar mecanismos de sincronismo no acesso a variveis comuns inter threads. Mquina da Sr.Tobias Saldo2=conta.getSaldo()
2 Sincronizao no Java
2.1 A Keyword Syncronized
Para tornar uma classe utilizvel em ambientes multithreads, est disponvel, a possibilidade de declarar alguns dos seus mtodos como synchronized Se uma thread, evocar num dado objecto, um mtodo declarado como synchronized este objecto bloqueado (locked) e outra thread que tente aceder-lhe s o conseguir quando este ficar disponvel (liberto do lock). luz destas consideraes a classe conta, do exemplo inicial, poderia ser rescrita da seguinte forma: class Conta { private double saldo; public Conta (double depositoInicial) { saldo= depositoInicial; } public synchronized double getSaldo() { return saldo; }
2/4
public synchronized void deposito (double quantia){ saldo+=quantia; } } Nota: essencial a utilizao de mtodos (synchronized) para aceder ao atributos da classe declarados como private (invs de protected ou mesmo publico) para manter a consistncia dos dados.
Se o valor de um atributo pode mudar, ento nunca dever ser lido ao mesmo tempo que outra thread pode escreve-lo. Por este motivo que ambos os mtodos (getSaldo() e deposito(...)) foram declarados synchronized. Contudo note-se que no garantia da ordem de execuo se uma leitura de saldo se iniciar primeiro terminar primeiro que um deposito e vice-versa. Se for necessrio assegurar a ordem das operaes, tero de ser utilizados mecanismos na aplicao que a assegurem. Exemplo: Considere que o Sr Tobias consultou o saldo e obteve 300, seguidamente tenta realizar um levantamento de 290 e a mquina diz-lhe que no tem saldo disponvel! O que aconteceu? De facto, a Sr Tobias realizou um levantamento de 100 noutra mquina multibanco entre as operaes de consulta e levantamento do Sr. Tobias. O sistema comportou-se como era suposto, uma vez que as consultas e levantamentos foram consistentes (devido utilizao de mtodos syncronized), contudo era prefervel que o sistema no permiti-se este comportamento. A soluo ser que a aplicao implemente mecanismos que permitam que o bloqueio do objecto conta bancria, se estendam a uma sesso do utilizador e no somente s operaes avulsas. Tal normalmente implementado recorrendo a uma flag (busy flag), que permite definir quando possvel aceder a atributos crticos.
3/4
2.4 Herana
Quando numa especializao de uma classe se sobrepe um mtodo synchronized, o novo mtodo pode ser ou no synchronized. No entanto o mtodo da super classe quando evocado manter-se- synchronized. Logo se o mtodo especializado evocar super, o objecto no qual este foi evocado, ser bloqueado at mtodo da classe progenitora retornar.
Notas: 1. No possvel seleccionar qual a thread que eu pretendo notificar, por isso importante que se utilize quando sabemos que threads esto espera, de qu e em que altura. 2. Se no houver threads em wait, o notify no faz nada. 3. Estes mtodos s podem ser evocados dentro de cdigo sincronizado, se assim no for lanada um excepo IllegalMonitorStateException. 4. A diferena entre o mtodo sleep() e o mtodo wait() que o primeiro baseia-se essencialmente na temporizao, no considerando notificaes para retomar execuo. 4/4