Problem producent konsument

0

Czesc mam problem z pewnym zadaniem w javie. A mianowicie mam napisac program wielo-watkowy w ktorym bedzie wystepowc 1 producent i wielu konsumentow, którzy korzystaja ze wspolnego pojemnika (pojemnikiem tym ma byc linkedList zaimplementowana jako kolejka).

Problem w tym ze nie moge schynchronizowac producenta z konsumentmi tak aby sie wzajemnie nie blokowali. Siedze juz caly dzien probuje roznych kombinacji ale caly czas gdzies program sie blokuje.

Ponizej wklejam kod ktory do tej pory napisalem. Jesli ktos zna sie na watkach to bardzo prosze o pomoc.

package testpr2;

class Towar
{
int kod;
double cena;
private static int i = 0;
private int count = i++;

public Towar()
{
kod = (int)(Math.random()*10000);
cena = (Math.random() * 1000);
if(count == 100)
{
System.out.println("Producentowi skonczyly sie surowce");
System.exit(0);
}
}

public String toString()
{
return "kod: " + kod + "cena: " + cena;
}
}

import java.util.*;

class Pojemnik
{
private final int MAX = 30;
LinkedList list = new LinkedList();

synchronized public Towar pobierz()
{
if(isEmpty())
{
try
{
wait();
}catch(InterruptedException e){}
}
Towar t = ((Towar)(list.removeLast()));
notifyAll();
return t ;
}

synchronized public void wstaw(Towar t)
{
	if(isFull())
 	  {
 		try
 		{
 			wait();
 		}catch(InterruptedException er){}
 	  }
 	  list.addFirst(t);
 	notifyAll();
}

synchronized public boolean isFull()
{
	if(list.size() == MAX)
		return true;
	else
		return false;
}

synchronized public boolean isEmpty()
{
  return (list.isEmpty());
}

synchronized Towar peek()
{
 return ((Towar)list.peek());
}

synchronized int size()
{
	return list.size();
}

}

class Producent extends Thread
{
Konsument k = new Konsument();
Pojemnik p;

Producent(){};
Producent(Pojemnik p)
{
	this.p =p;
	start();
}
public void run()
{
	while(true)
	{	
		while(!p.isFull())
		synchronized(this)
		{
			  Towar t = new Towar();
			  p.wstaw(t);
			  synchronized(System.out){
			  System.out.println(this + " " + p.size());}	
			  try
			  {
				   k.join();
			   }catch(InterruptedException er){}  
		}
			  
      synchronized(k)
      {
    	  k.notifyAll();
      }
	}
}

		public String toString()
		{
			return "Producent dodal towar " + p.peek();
		}

}

class Konsument extends Thread
{
private static int counter = 0;
Pojemnik p;

Konsument()
{}
Konsument(Pojemnik p)
{
	super("" + ++counter);
	this.p = p;
	start();
}

public void run()
{
	while(true)
	{
	while(p.isEmpty())
	synchronized(this)
	{
	  try
	  {
		wait();
	  }catch(InterruptedException er){}
	}
	synchronized(System.out){  
	System.out.println(this + " "+p.pobierz()+ " " +p.size());}
	 
	 
	}   
		
}
public String toString()
{
	return "Konsument " + getName() + " pobral towar ";
}

}

public class ProducentKonsument
{
public static void main(String[] args)
{
Pojemnik poj = new Pojemnik();

	new Producent(poj);
	for(int i=0; i<13 ;i++)
	new Konsument(poj);
				
}

}

0

tez dostalem identyczny problem (na trzonie programu z 1 prod i 1 kons i pojemnikiem magazynujacym jedno dobro naraz, rozbudowac do 1 prod i wielu kons i pojemnikiem linkedlist) i wstepnie rozwiazalem go w taki sposob:

import java.util.*;

class Pojemnik
{
int max;
LinkedList lista = new LinkedList();
boolean koniecProdukcji;
Pojemnik (int max)
{
this.max = max;
koniecProdukcji = false;

}
synchronized void put( Towar t )
{
	if( lista.size() == max )
	{
		try
		{
			wait();
		}
		catch (InterruptedException e) {}
	}
	lista.add(t);
	System.out.println("Produkcja: " + t.toString() );
	notify();
}

synchronized int get ()  // zwraca 1 jak zje i 0 jak nie zje
{
	if ( (lista.size() == 0 ) && ( koniecProdukcji == false ) )
	{
		try
		{
			wait();
		}
		catch(InterruptedException e) {}
	}
	Object kosz;
	try
	{
			kosz = lista.removeFirst();
			System.out.println("Konsumpcja: " + kosz.toString() );
			notify();
			return 1;
	}
	catch (NoSuchElementException e) {return 0;}
}
synchronized void zamknijProdukcje () 
{
	 koniecProdukcji = true;
	 notifyAll(); *producent uruchamia wszystkich konsumentow, jeden zje towar a reszta trafi     *na wyjatek z pusta lista
}
synchronized boolean czyPustyForever()	
{
	if ( (lista.size() == 0) && (koniecProdukcji == true) ) 
	{
		return true;
	}
	else
	{
		return false;
	}
}

}
class Producent implements Runnable
{
Pojemnik p;
int wielkoscProdukcji;
Producent(int wielkoscProdukcji,Pojemnik p)
{
this.p = p;
new Thread(this).start();
this.wielkoscProdukcji = wielkoscProdukcji;
}
public void run()
{
for (int i = 1; i <= wielkoscProdukcji; i++)
{
p.put(new Towar());
if ( i == wielkoscProdukcji) break;
try
{
Thread.sleep( (int) (Math.random() * 5000) );
}
catch (InterruptedException e) {}
}
System.out.println("prodakszyn komplityt");
p.zamknijProdukcje();
}
}
class Konsument extends Thread
{
Pojemnik p;
String name;
int ilePozarl;
Konsument(String name,Pojemnik p)
{
this.setName(name);
this.p = p;
this.start();
ilePozarl = 0;
}
public void run()
{
while (p.czyPustyForever() == false)
{
ilePozarl += p.get();
try
{
Thread.sleep( (int) (Math.random() * 5000) );
}
catch (InterruptedException e) {}
}
System.out.println(this.getName() + " pozarl " + ilePozarl + " snikersow" );
}
}

class Towar
{
int kod;
double cena;

Towar()
{
	kod = ( (int) (Math.random() * 100000) );
	cena = ( Math.random() * 1000); 
}
public String toString()
{
	return "Kod: "+kod+" cena: " + cena;
}

}

class pr1zad22proba
{
public static void main( String args[])
{
Pojemnik p = new Pojemnik(3);
new Producent(10,p);
for (int b =1; b<=10;b++)
new Konsument("Jesus Honey " +b,p);
}
}

Pozdrawiam.

1 użytkowników online, w tym zalogowanych: 0, gości: 1