Bom dia Pessoal!!! Eu to com um programa aqui, que infelizmente está lançando um
IllegalMonitorStateException…olha só:
minha thread usuario onde eu crio uma forma, mando essa forma lá pra thread maquina…
e aqui está onde tudo acontece quando o programa alcança a linha para a chamada de notify() ele lança a exceção,
pelo código eu imagino, que minha thread usuario possui o lock da minha List formas, mas não tô entendo o porquê
dessa exceção, então gostaria da ajuda de vocês pra resolver isso : ). Desde já agradeço!!!
Tem como postar o código aqui? Essas imagens são bloqueadas pelo proxy aqui da empresa.
O notify() é chamado em uma lista? Se for, você deu um wait() na lista antes de enviá-la para outra Thread?
Outra coisa, apenas uma thread está esperando o notify? Se não for, invoque o método notifyAll()
R
romariowd
Tem sim Leonardo Olha ai o código:
publicclassUsuarioextendsThread{Maquinam;<aclass="mention" href="/u/override">@Override</a>public void run(){Forma f;// int c =Integer.parseInt(JOptionPane.showInputDialog(“Informe o comprimento da peça”));// int d =Integer.parseInt(JOptionPane.showInputDialog(“Informe a largura da peça”));f = new Forma(10,20);m = new Maquina();m.addForma(f);
System.out.println(Thread.currentThread().getName()+" Obteve as formas do usuário");System.out.println("Enviado as formas para a Thread Máquina");
}
}
Da classe Maquina:
public class Maquina extends Thread{
List formas = new ArrayList<>();
publicvoidaddForma(Formaf){synchronized(formas){System.out.println("Run by : "+Thread.currentThread().getName());formas.add(f);notify();}}@Override
publicvoidrun(){while(true){synchronized(formas){while(formas.isEmpty()){try{System.out.println("Run by : "+Thread.currentThread().getName());
Tem como postar o código aqui? Essas imagens são bloqueadas pelo proxy aqui da empresa.
O notify() é chamado em uma lista? Se for, você deu um wait() na lista antes de enviá-la para outra Thread?
Outra coisa, apenas uma thread está esperando o notify? Se não for, invoque o método notifyAll()
Pois é leonardo eu chamei wait(), mas não está adiantando nada…
ivandasilva
No javadoc de Object fala
ivandasilva
A Thread Usuario está sendo executada e tenta fazer a notificação de um objeto que pertence a Maquina, quem tem o lock da sua lista é o objeto Maquina e não Usuario.
R
romariowd
Mas Ivandasilva, quando eu chamo o wait() para parar a Thread Maquina, ela deveria entregar o lock para a Thread Usuario não??
e a minha thread usuario ele consegue entrar dentro do bloco synchronizado, e adicionar o objeto para a List, então se quem
possui o lock é a minha thread máquina então minha thread lock não poderia nem executar a primeira linha do bloco sincronizado,
ou eu estou errado??
ivandasilva
Mas Ivandasilva, quando eu chamo o wait() para parar a Thread Maquina, ela deveria entregar o lock para a Thread Usuario não??
e a minha thread usuario ele consegue entrar dentro do bloco synchronizado, e adicionar o objeto para a List, então se quem
possui o lock é a minha thread máquina então minha thread lock não poderia nem executar a primeira linha do bloco sincronizado,
ou eu estou errado??
Vc chama o wait() o lock vai para a Thread Usuario, ela entra no bloco sincronizado, adiciona o objeto… mas o monitor neste caso é sua lista que não pertence a Thread Usuario e sim Maquina, quem está sendo executado é Usuario, mas o objeto monitor que é sua lista pertence a classe máquina…
agora só um parentesis posso estar falando grosélia !! Não manjo muito de multithread…
R
romariowd
ivandasilva:
Mas Ivandasilva, quando eu chamo o wait() para parar a Thread Maquina, ela deveria entregar o lock para a Thread Usuario não??
e a minha thread usuario ele consegue entrar dentro do bloco synchronizado, e adicionar o objeto para a List, então se quem
possui o lock é a minha thread máquina então minha thread lock não poderia nem executar a primeira linha do bloco sincronizado,
ou eu estou errado??
Vc chama o wait() o lock vai para a Thread Usuario, ela entra no bloco sincronizado, adiciona o objeto… mas o monitor neste caso é sua lista que não pertence a Thread Usuario e sim Maquina, quem está sendo executado é Usuario, mas o objeto monitor que é sua lista pertence a classe máquina…
agora só um parentesis posso estar falando grosélia !! Não manjo muito de multithread…
Pois é Ivan mas quem possui a bola da vez é a thread usuario (eu acho né), porque a thread maquina entregou o seu lock,
então Teoricamente a thread maquina deveria estar esperando por uma notificação sob o objeto List…
Eu vi esse exemplo no livro da Kathy sierra só mudei algumas coisas… mas o método add e o objeto List<> está na
mesma forma do livro,estão na classe máquina, e as duas threads utilizam o lock da List<>… então qual seria a solução pra
isso??
ivandasilva
[email removido] manda para o meu e-mail, vou montar em casa e ver, sinceramente, não sei se estou certo. Uma tentativa, troque o objeto que faz o lock, troca por this…
R
romariowd
beleza vou mandar, eu fiz o que você falou, mudei pra this, mas a mensagem dizendo que a thread maquina acordou
nunca é exibida e nem a mesagem mais embaixo “eai”…
ivandasilva
troca o notify() por notifyAll(), alias, esqueça o notify() prefira o notifyAll()
rogeriopaguilar
Na classe usuário você está criando a classe máquina. Na verdade você tem que criar uma instância apenas da classe máquina, chamar start nesta instância e compartilhar esta instância com a classe usuário. Além disso, o notify você deve chamar no objeto formas e não o notify da classe Maquina. No código abaixo eu corrigi estes pontos.
Outra coisa, quando postar código coloque sempre entre as tags code (apertando o botão code acima).
packageteste.concorrencia;importjava.util.ArrayList;importjava.util.List;importjava.util.logging.Level;importjava.util.logging.Logger;classMaquinaextendsThread{List<Forma>formas=newArrayList<>();publicvoidaddForma(Formaf){synchronized(formas){System.out.println("Run by : "+Thread.currentThread().getName());formas.add(f);formas.notify();}}@Overridepublicvoidrun(){while(true){synchronized(formas){while(formas.isEmpty()){try{System.out.println("Run by : "+Thread.currentThread().getName());formas.wait();System.out.println("Olá! Thread Máquina acordou");}catch(InterruptedExceptionex){Logger.getLogger(Maquina.class.getName()).log(Level.SEVERE,null,ex);}}//System.out.println("eai");}}}}publicclassUsuarioextendsThread{Maquinam;publicUsuario(Maquinam){this.m=m;}@Overridepublicvoidrun(){Formaf;// int c// =Integer.parseInt(JOptionPane.showInputDialog("Informe o comprimento da peça"));// int d// =Integer.parseInt(JOptionPane.showInputDialog("Informe a largura da peça"));f=newForma(10,20);//m = new Maquina();System.out.println(Thread.currentThread().getName()+" Obteve as formas do usuário");System.out.println("Enviado as formas para a Thread Máquina");m.addForma(f);}publicstaticvoidmain(Stringargs[]){Maquinamaquina=newMaquina();maquina.start();Usuario[]usuario=newUsuario[5];for(inti=0;i<5;i++){usuario[i]=newUsuario(maquina);usuario[i].start();}}}
R
romariowd
beleza fiz isso também, mas o problema ainda continua
R
romariowd
Valeu rogerio agora sim funfou legal!!! Muito Obrigado
R
romariowd
Eu estava criando duas istancias de maquina, por isso que não estava dando certo…
ivandasilva
E quem estava fazendo o notify() não era o objeto monitor, sua lista e sim a classe máquina.