Problema ConsumidorXProdutor com 3 threads,mas só duas threads conseguem consumir.[Resolvido]

1 resposta
D

Boa tarde, pessoal tentando entender um pouco as threads tentei implementar o problema do ProdutorXConsumidor
a implementação consiste nas seguintes classes:
Produtor:

public class Produtor {
List<Produto> produtos=new ArrayList<Produto>();  
boolean producao=true;
public synchronized void produzir(){
 Produto[]produto=new Produto[]{new Produto("Carne"),new Produto("cereais"),new Produto("Sushi"),new Produto("Juicy")};
 if(produtos.size()==0){
	 for(int i=0;i<4;i++){
	  produtos.add(produto[(int)(Math.random()*3)]);	 
	}
	 producao=false;
	 notifyAll(); 
}
}
public  void consumir(){
	System.out.println("Seguinte thread chegou para consumir   "+Thread.currentThread().getName());
	synchronized (this) {
		if(produtos.size()==0){
			produzir();
		    notifyAll();
		}	
		else{
			System.out.println("Seguinte thread  vai consumir a lista  "+Thread.currentThread().getName());
			for(int i=0;i<produtos.size();i++){
			produtos.remove(i);
			}	
			notifyAll();	
			produzir();
		}	
		}//Fim do bloco syncronizado }
public List<Produto> getProdutos() {
	return produtos;
}
public void setProdutos(List<Produto> produtos) {
	this.produtos = produtos;
}
public boolean isProducao() {
	return producao;
}
public void setProducao(boolean producao) {
	this.producao = producao;
}
}

Consumidor:

public class Consumidor extends Thread {
Produtor produtor;
public Consumidor(String nome,Produtor produtor){
	super(nome);
	this.produtor=produtor;
}
public  void run(){
	synchronized (this) {
		while(true){
			if(!produtor.isProducao()){//O produtor está produzindo devo aguardar 
				try {
					wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				}
			else{
				produtor.consumir();	
				
				}
}
		
}
}}

E a classe de teste:

public class Teste { public static void main(String[] args) { // TODO Auto-generated method stub Produtor produtor=new Produtor(); Consumidor c1=new Consumidor("João",produtor); Consumidor c2=new Consumidor("Paulo",produtor); Consumidor c3=new Consumidor("Franciso",produtor); c1.start(); c2.start(); c3.start(); } }

O código funciona, mas somente duas threads conseguem consumir.Onde eu posso estar errando?
Outra dúvida o IllegalThreadMonitorExecption só é lançado quando eu chamo o wait em contexto não syncronizado??

Eu agradeço qualquer resposta.

1 Resposta

D
Consegui resolver a parte de threads estava certa tinha umas de lógica, tinha que chamar o metodo consumir mesmo que lista estivesse vazia. Ficou assim o código: Produtor
public class Produtor {
List<Produto> produtos=new ArrayList<Produto>();  
boolean producao=true;

public  void produzir(){
 
 Produto[]produto=new Produto[]{new Produto("Carne"),new Produto("cereais"),new Produto("Sushi"),new Produto("Juicy")};
 
 if(produtos.size()==0){
	 for(int i=0;i<4;i++){
	  produtos.add(produto[(int)(Math.random()*3)]);	 
	
	 }
	
	 producao=false;
	 notifyAll(); 
}
}


public  void consumir(){
	System.out.println("Seguinte thread chegou para consumir   "+Thread.currentThread().getName());
	
	synchronized (this) {
		
		if(produtos.size()==0){
			produzir();
		    
		}	
		else{
			System.out.println("Seguinte thread  vai consumir a lista  "+Thread.currentThread().getName());
			for(int i=0;i<produtos.size();i++){
			produtos.remove(i);
			
		}	
			
				
			
		}	
			
		
		}//Fim do this 
	
	
	}
	
	
	
	
	
	
	
	



public List<Produto> getProdutos() {
	return produtos;
}


public void setProdutos(List<Produto> produtos) {
	this.produtos = produtos;
}


public boolean isProducao() {
	return producao;
}


public void setProducao(boolean producao) {
	this.producao = producao;
}


}
Consumidor
public class Consumidor extends Thread {
Produtor produtor;

public Consumidor(String nome,Produtor produtor){
	super(nome);
	this.produtor=produtor;
	
	
	
}
public  void run(){
	while(true){
	synchronized (this) {
		
	
		
			if(!produtor.isProducao()){
				try {
					System.out.println("A seguinte thread está aguradando produção "+Thread.currentThread().getName());
					produtor.consumir();
					wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				}
			else{
				produtor.consumir();	
				
				
			}
			
			
			
				
			
			
			
			
		}
		
			
		
		
		
		
		
			
		
		
		
	}
}
	}

A classe de Teste e produto são as mesmas.

Criado 1 de abril de 2009
Ultima resposta 2 de abr. de 2009
Respostas 1
Participantes 1