Notify() IllegalMonitoStateException [RESOLVIDO]

16 respostas
R

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!!!

16 Respostas

Leonardo_Gaona

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

Tem sim Leonardo Olha ai o código:

public class Usuario extends Thread{

Maquina m;

<a class="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<>();

public  void addForma(Forma f){
  synchronized(formas){
    System.out.println("Run by : "+ Thread.currentThread().getName());
      formas.add(f);
   notify();
  }
    
}
@Override
public void run(){

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 (InterruptedException ex) {
            Logger.getLogger(Maquina.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    System.out.println("eai");
}

}
}
}

R

Leonardo Gaona:
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

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

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

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”… :confused:

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).

package teste.concorrencia;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

class Maquina extends Thread {
	List<Forma> formas = new ArrayList<>();

	public void addForma(Forma f) {
		synchronized (formas) {
			System.out.println("Run by : " + Thread.currentThread().getName());
			formas.add(f);
			formas.notify();
		}
	}

	@Override
	public void run() {
		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 (InterruptedException ex) {
						Logger.getLogger(Maquina.class.getName()).log(
								Level.SEVERE, null, ex);
					}
				}
				//System.out.println("eai");
			}
		}
	}
}

public class Usuario extends Thread {
	Maquina m;
	
	public Usuario(Maquina m) {
		this.m = m;
	}
	

	@Override
	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();

		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);
	}
	
	public static void main(String args[]) {
		Maquina maquina = new Maquina();
		maquina.start();
		Usuario[] usuario = new Usuario[5];
		for(int i = 0; i < 5; i++) {
			usuario[i] = new Usuario(maquina);
			usuario[i].start();
		}
		
	}
	

}
R

beleza fiz isso também, mas o problema ainda continua :cry:

R

Valeu rogerio agora sim funfou legal!!! Muito Obrigado :smiley:

R

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.

Criado 21 de novembro de 2012
Ultima resposta 22 de nov. de 2012
Respostas 16
Participantes 4