| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 23/10/2010 04:45:35
|
Jaba
JavaGuru
![[Avatar]](/images/avatar/6cf8ae4c2312ba4a0103e20d0ace1ea3.jpg)
Membro desde: 08/08/2008 20:56:54
Mensagens: 243
Offline
|
Pessoal, e o seguinte:
Em threads, usamos blocos sincronizados dessa maneira:
Nesse caso, o MyClass.class representa a classe de que todos os objetos herdam. O livro da Kathy chama esse conteudo do parenteses de depósito. Ai em cima, como eu usei o MyClass.class, eu estou usando o bloqueio por classe, ou seja: somente uma instancia pode acessar esse método.
A minha dúvida é a seguinte:
Eu já vi vários parametros nesse depósito, por exemplo, a palavra chave "this", que no caso, acabaria com o bloqueio por classe e faria o bloqueio ser por instancia novamente, que no caso, seria a instancia chamadora.
Mas tambem já vi um exercicio do livro usando System.out, um exercicio do ExamLab usando foo, que era uma classe declarada diferente que a thread estava usando... Resumindo: eu estou confuso e não sei o que eu posso colocar nesse "depósito" e as implicações dependendo do que eu colocar, principalmente no bloqueio por class.
Alguem poderia esclarecer essa minha dúvida?
E, Obrigado novamente, pessoal!!!
This message was edited 2 times. Last update was at 23/10/2010 04:49:51
|
OCWCD - Oracle Certified Web Component Developer
OCJP - Oracle Certified Java Programmer
KET - Key English Test
PET - Preliminary English Test |
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 23/10/2010 08:46:18
|
ViniGodoy
Moderador
![[Avatar]](/images/avatar/1921493b5362e63fbe8983f4bd54157d.png)
Membro desde: 11/12/2006 08:22:01
Mensagens: 20580
Localização: Curitiba/PR
Offline
|
Aquele objeto que vai dentro do bloco sincronizado, é quem controla quem pode ou não entrar no bloco. Duas threads irão se bloquear se aquele objeto for o mesmo. O notify() irá apenas notificar quem estiver esperando num wait() dado num mesmo objeto. Primeiro, para responder à sua pergunta, é necessário entender porque existe sincronização. Sincronização existe para impedir que duas threads acessem simultaneamente a mesma área de memória. Essa área de memória é chamade de região crítica. O problema é que duas threads alterando a região crítica ao mesmo tempo podem, de vez enquando, fazer modificações indesejadas nos dados. Pois bem. Dois objetos diferentes, dados com new diferentes, ocupam áreas de memória diferentes. Portanto, não há problema que uma thread percorra um objeto e outra outro objeto, ao mesmo tempo. Note que estou falando de objetos, não de classes. Por isso, ocorre sincronização no this. Ela garante que cada thread acesse exclusivamente aquele objeto. E que threads possam acessar simultaneamente dois objetos distintos daquela classe. Acessar coisas de maneira simultânea é bom, é justamente o que quereremos quando trabalhamos com threads. Uma boa aplicação multi-threading tem por obrigação maximizar o paralelismo. Entretanto, temos um tipo de variável chamado static. Esse tipo é compartilhado por todos os objetos de uma classe. Isso força com que a sincronização não possa ser feita em this. Se for feita, duas threads simultâneas irão acessar dois objetos distintos ao mesmo tempo e, quando chegarem no ponto onde o static é usado, irão altera-lo ao mesmo tempo, pois ele é compartilhado. Dessa forma, temos ali uma região crítica compartilhada, que ainda está permitindo acesso mútuo. Nesse caso, você é obrigado a usar o synchronized no mesmo objeto para todas as threads. Como garantir isso? A forma mais simples é usar no synchronized um outro objeto estático. Como esse objeto será compartilhado tanto quanto sua variável, todas as threads irão parar. Note que essa solução tem menos paralelismo que a anterior. Na verdade, ela praticamente elimina a vantagem de se trabalhar com threads, já que, para o objeto que faz isso, todas as threads serão enfileiradas, independente da instância utilizada. Esse é um dos motivos pelo qual synchronized é ruim para threads. Bom, entendida essa diferença, vamos falar agora sobre usar o this e o class, versus usar um objeto próprio. De maneira geral, é melhor usar um objeto próprio para fazer a sincronização. Esse objeto deve ser declarado só para esse fim, e ser um atributo privado da classe: O mesmo vale para statics. Essa abordagem tem a vantagem de não gerar problemas, caso alguém resolva usar um objeto de sua classe dentro de um bloco synchronized. Entretanto, mas essa forma é um pouco verborrágica. Se usada direito, a forma padrão do java também atende as necessidades. Isto é, usar a sincronização em this e em Classe.class. Entretanto, se você adotar esse estilo, passa a ser uma péssima prática usar objetos de outras classes para fazer a sincronização. Por exemplo: Note que como Classe sincroniza pelo this, e Classe2 está sincronizando por um objeto do tipo Classe, os dois estão, de fato, usando a mesma chave de sincronização! E isso pode gerar coisas nefastas, como deadlocks imprevistos (e note também que a solução anterior, que apontei como melhor não sofre desse problema). Por isso, sincronizar em outros objetos, como System.out, ou classes diferentes pode ser perigoso. O livro talvez faça isso apenas a título de exemplo, para dizer que é possível. Mas é uma péssima prática.
This message was edited 1 time. Last update was at 23/10/2010 08:50:07
|
@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 |
|
|
 |
|
|
|
|