Pessoal, estou com um sistema que executa 10 threads simultaneamente, no entanto, existe um pedaço do código (método) que não pode ser executado por mais de um thread ao mesmo tempo e portanto eu tenho de sincronizar este método.
Eu usei o synchronized na assinatura do método, no entanto, isso não está sendo suficiente, visto que mais de uma thread está entrando no método ao mesmo tempo.
Alguém pode me dar uma dica de qual solução devo adotar?
Pelo que eu sei quando um um método e marcado synchronized, o sistema de execução Java garantirá que apenas uma thread de cada vez acesse tal método. Se outras threads tentarem fazer o mesmo, elas serão colocadas em espera até que a thread atual finalize seu trabalho e libere o método. Acho que vc esta enganado …poste i seu codigo … flw
não senhores…o synchronized é no caso de duas threads chamarem o metodo ao mesmo tempo…ele garante que seja um depois da outra…ele dar um pequeno pause na thread 2 enqaunto a thread1 chama o metodo e depois libera pra 2…agora nesse seu caso :S…vou dar uma olhada aqui
synchronized: apenas uma Thread executa o trecho por vez. Necessariamente.
Pergunta: você está com problema em um laço for (ou Iterator), onde percorre algo tipo de Collection (como ArrayList, por exemplo)? Pode ocorrer (e muitas vezes ocorre) um ConcurrentModificationException quando se tenta adicionar ou remover objetos em uma Collection.
Mas o meu caso é justamente esse, eu quero que a 2ª thread espere a 1ª executar o metodo para depois executá-lo.
O método que quero sincronizar é um método do meu DAO e ele tem a seguinte assinatura:
public synchronized Map<Protocolo, ByteArrayOutputStream> getFirstLote() {
.....
}
Todas as threads utilizam o mesmo DAO que possui o método acima.
O DAO está sendo injetado na Thread via SPRING, mas acho que isso não tem nada a ver né.
Algum idéia?
Você viu o que escrevi acima?
O abelgomes é o que mais se aproximou, mas ainda está errado.
Você tem um bloco synchronized (vou falar de blocos antes de falar dos métodos). Então você terá algum código mais ou menos assim:synchronized (abacaxi) {
// blablabla
}
Quando a Thread chega no synchronized, ela tenta reservar o objeto abacaxi. Qualquer objeto pode servir como reserva.
Ao reservar o objeto abacaxi, a Thread se torna “dona” deste objeto, e só o larga quando sai do bloco synchronized.
Se a Thread A for dona de abacaxi (está sincronizando nele), e a Thread B tenta reservar o mesmo objeto abacaxi, ela vai ver que já foi reservado para outra Thread. Daí a Thread B espera que a Thread A largue o objeto abacaxi, para poder reservá-lo.
Se a Thread X for dona do objeto melancia e houver outras 50 Threads esperando para reservar o objeto melancia, quando a Thread X o largar, alguma das Threads que estão esperando por melancia vai ser sorteada com ele. Não há fila pela reserva, e sim sorteio.
Se a Thread A está sincronizando no objeto mamão e a Thread B no objeto beterraba, uma não influencia a outra. Estão sincronizando em objetos diferentes.
O synchronized no método é apenas um synthatic sugar:public synchronized void xxx() {
// blablabla
}
É o mesmo quepublic void xxx() {
synchronized (this) {
// blablabla
}
}
Observe que o objeto usado para sincronizar é this. Desta forma, se a Thread A chama um método sincronizado da instância X e a Thread B chama um método sincronizado da instância Y, elas estarão sincronizando em objetos diferentes. Logo, ambos podem executar ao mesmo tempo.
Se a Thread A chama o método sincronizado x da instância H e a Thread B chama um outro método sincronizado y da mesma instância H, só uma executa de cada vez, pois estão sincronizando no mesmo objeto.
Para métodos estáticos, fica assim:public static synchronized void xxx() {
// blablabla
}
É o mesmo quepublic static void xxx() {
synchronized (EstaClasse.class) {
// blablabla
}
}
Ou seja, sincroniza-se no objeto class correspondente.
Espero ter esclarecido.
perfect…