problemas com concorrencia. synchonized nao esta surtindo efeito  XML
Índice dos Fóruns » Java Avançado
Autor Mensagem
rbamartins
JavaEvangelist
[Avatar]

Membro desde: 01/03/2007 16:10:11
Mensagens: 362
Localização: Salvador
Offline

Galera,

estou com o seguinte problema de concorrência.

Tentamos assinar toda o método com o synchronized (sei que nao é a melhor forma, pois honera muito o processamento) mas mesmo assim não funciona. As duas chamadas estão entrando ao mesmo tempo e embaralhando o array de indices que estava sendo formado. E assim acabo numa exception do tipo IndexOutOfBound.

Para tentar melhorar a perfomance tentei criar alguns blocos de synchronized nas regiões que considerava críticas.

Esse é uma parte do código um dos métodos que estamos tentando sincronizar.




Tentei tratar com blocos de synchronized dentro deste método que é minha região critica de verdade onde ele embaralha o indice e me encerra o processamento.



Se alguém puder me dar uma luz ou me mostrar o ponto onde estou falhando. Pois o syncronized não está surtindo efeito, ele entra com as duas solicitões mesmo que eu assine o método com o synchronized e ocorre tudo que já expliquei aqui.

Abraços a todos.


Rafael Britto A. Martins
http://rafaelmartinsjava.blogspot.com


"Um homem forte se defende sozinho, o homem mais forte defende os outros."
[Email] [WWW] [MSN]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Logo de cara já parece haver um problema no seu código:


Quantos objetos do tipo "diretor" são criados pelo seu código? Um para todas as threads ou um por thread? Dá a impressão (o código é muito comprido e não consegui lê-lo todo) que há um objeto "diretor" por thread; se for isso, nunca haverá sincronização, já que a sincronização por definição envolve várias threads.
"synchronized (this)" (em outra parte do seu código) também não funciona se existir um "this" para cada thread.
[WWW]
rbamartins
JavaEvangelist
[Avatar]

Membro desde: 01/03/2007 16:10:11
Mensagens: 362
Localização: Salvador
Offline

thingol wrote:Logo de cara já parece haver um problema no seu código:


Quantos objetos do tipo "diretor" são criados pelo seu código? Um para todas as threads ou um por thread? Dá a impressão (o código é muito comprido e não consegui lê-lo todo) que há um objeto "diretor" por thread; se for isso, nunca haverá sincronização, já que a sincronização por definição envolve várias threads.
"synchronized (this)" (em outra parte do seu código) também não funciona se existir um "this" para cada thread.


Thingol, obrigado pela resposta.

É assim... na verdade é criada um objeto do tipo "diretor" por chamada ao processo.

Nós estamos fazendo testes simultâneos através do browser e queremos impedir que o método construirMensagemTiss da clase diretor seja executado ao mesmo tempo. Por isso tentamos fazer dessa forma mostrada abaixo:



Mas, ainda sim ele permite a chamada dupla e depois embaralha meu indice do array.

:(
[Email] [WWW] [MSN]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline


Nós estamos fazendo testes simultâneos através do browser e queremos impedir que o método construirMensagemTiss da clase diretor seja executado ao mesmo tempo. Por isso tentamos fazer dessa forma mostrada abaixo:


Aham, ainda assim quero saber quantos objetos dessa classe estão instanciados em um determinado momento. Essa classe roda em um servlet, um EJB, onde?
[WWW]
rbamartins
JavaEvangelist
[Avatar]

Membro desde: 01/03/2007 16:10:11
Mensagens: 362
Localização: Salvador
Offline

thingol wrote:
Aham, ainda assim quero saber quantos objetos dessa classe estão instanciados em um determinado momento. Essa classe roda em um servlet, um EJB, onde?


Roda num servlet.

Apenas um objeto está sendo instanciado para essa classe neste momento.
Para cada vez que alguém faz uma nova chamada ele dá um new e cria uma nova referência.

Thingol, desculpe mas não sei se estou conseguindo ser claro em minhas dúvidas.





[Email] [WWW] [MSN]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Eu na verdade estou fazendo um monte de perguntas, sem ver (ou entender) exatamente os detalhes do seu problema, esperando que você é que consiga resolvê-lo (método "socrático").

1) Se você está usando uma servlet, normalmente as servlets são multithreaded (ou seja, apenas uma instância da classe derivada de HttpServlet é criada por web container). Veja se por engano você não especificou (no web.xml) que a servlet é "single-threaded" (ou seja, uma instância da classe servlet é criada por requisição). Se você fez isso (usou "single-threaded" em vez de "multi-threaded"), aí fica mais complicado. Certifique-se que sua servlet é "multithreaded".
2) Se para cada requisição você está criando um novo objeto Diretor, então você não pode sincronizar sobre esse objeto Diretor; você tem de sincronizar por algum campo do objeto servlet - já que há apenas um objeto desses, não?
Você pode até criar um objeto como campo do objeto servlet (mais ou menos assim: Object lock = new Object();) só para sincronizar por ele.)
3) Nem olhei o que o "this" representava - não olhei direito seu código.

[WWW]
rbamartins
JavaEvangelist
[Avatar]

Membro desde: 01/03/2007 16:10:11
Mensagens: 362
Localização: Salvador
Offline

Thingol

Tivemos que alterar a declaração de nosso método para static synchornized e fizemos a seguinte alteração em um trecho que chama o método que vai chamar a região crítica, como:



E no final do método gerarXML demos um notify() para liberar o processo.

Vemos que ainda não é a melhor solução para o caso, pois o processo da geração do XML é muito custoso e da forma que está sendo feita agora ele espera todo o processo terminar para começar o próximo.
Estamos de imediato tentando diminuir o processamento disso, pois dessa forma ele fica o tempo todo testando até que chegue a notificação, quero achar um tempo ideal para que eu consiga dar um wait nele e diminuir essa quantidade de testes.

E, também, a forma mais correta de utilizar o wait nesse caso.


Tentamos tirar esse tratamento daí e colocar algo semelhante dentro da nossa lib (que é onde cai na região crítica, porém lá da erro e o synchronized não funciona. Por isso, até agora estamos tendo que arcar com esse ônus de esperar um processamento para começar o outro.

Obrigado pela ajuda e pelo método de ensino "socrático" ... (risos)... Muito boa prática.

This message was edited 3 times. Last update was at 20/06/2008 10:00:07


Rafael Britto A. Martins
http://rafaelmartinsjava.blogspot.com


"Um homem forte se defende sozinho, o homem mais forte defende os outros."
[Email] [WWW] [MSN]
 
Índice dos Fóruns » Java Avançado
Ir para:   
Powered by JForum 2.1.8 © JForum Team