Programowanie współbieżne - alg. P-K

0

Witam wszystkich:

Mam taki problem - napisalem kod, ktory mial na celu realizowac algorytm producenta i konsumenta.
Jednak program nie dziala tak jak trzeba. W zasadzie nie wiem co robie zle. Wiem, jedno, ze funkcja wait() nie dziala tak jak powinna w tym programie.

Proszę o pomoc

Poniżej zamieszczam kompletny kod:


/*
   algorytm producent-konsument dla ograniczonego bufora = 10
 */

class Bufor04
{
	private int buf[];
	public int count;
	static final int RozmiarBufora = 10;

	public Bufor04() 
	{
		buf = new int[RozmiarBufora];
		count = 0;
	}

	synchronized public void WstawElement(int el)
	{
		buf[count] = el;
		count++;
	}

	synchronized public int PobierzElement()
	{
		int temp;
		temp = buf[count];
		count--;
		return temp;
	}
}

public class Zadanie
{
	public static void main(String args[])
	{
		Bufor04 bufor = new Bufor04();

		new Thread(new Producent(bufor)).start();
		new Thread(new Konsument(bufor)).start();

	}
}


class Producent implements Runnable
{
	private Bufor04 bufor;

	Producent(Bufor04 _bufor)
	{
		bufor=_bufor;
	}

	public void run()
	{
		System.out.println("uruchomiony watek producenta");
		while(true)
		{ 
			if(bufor.count == 10)
			{
				try 
				{ 
					System.out.println("bylem w wait, ale sobie wyszedlem, czemu?" );
					this.wait();
				} 
				catch(Exception e) {}
			}

			bufor.WstawElement(1);
			System.out.println("wstawiono cos: count= " + bufor.count );

			if(bufor.count == 1)
				notify();

			try 
			{
				Thread.currentThread().sleep(100);
			} 
			catch(InterruptedException e) {}    
		}
	}
}

class Konsument implements Runnable
{
	private Bufor04 bufor;

	Konsument(Bufor04 _bufor)
	{
		bufor=_bufor;
	}

	public void run()
	{
		System.out.println("uruchomiony watek konsumenta");
		while(true)
		{
			if(bufor.count == 0)
			{
				try 
				{ 
					wait(); 
				} 
				catch(Exception e) {}
			}

			int j=bufor.PobierzElement();
			System.out.println("skonsumowano: count= " + bufor.count );

			if(bufor.count == 9)
				notify();

			try 
			{
				Thread.currentThread().sleep(1000);
			} 
			catch(InterruptedException e) {}
		}
	}
}
0

Nie dziwnie się, że nie działa poprawnie skoro nie robisz sekcji krytycznych. Szczególnie chodzi o odwołania do bufor.count.

Inna sprawa, że tu chyba pomyliłeś kolejność instrukcji.

 System.out.println("bylem w wait, ale sobie wyszedlem, czemu?" );
this.wait();

Od Javy 5 dostępna jest standardowa klasa realizująca algorytm P-K.

http://java.sun.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html
http://java.sun.com/javase/6/docs/api/java/util/concurrent/ArrayBlockingQueue.html

0

Ok, dzieki za linki :)
Rzeczywiscie, nie bylo to umieszczone w sekcji krytycznej.

Ale juz pozmienialem trochę i dzialającą wersję umieściłem poniżej.

Zazczaczyłem momenty, w których trzeba zwracać uwagę na indeksy talicy.


/*
   algorytm producent-konsument dla ograniczonego bufora = 10
 */

class Bufor04
{
	private int buf[];
	public int count;
	static final int RozmiarBufora = 10;

	public Bufor04() 
	{
		buf = new int[RozmiarBufora];
		count = 0;
	}

	synchronized public void WstawElement(int el)
	{
		if(count == 10-1)
		{
			try 
			{ 
				System.out.println("bylem w wait, ale sobie wyszedlem, czemu?" );
				this.wait();
			} 
			catch(Exception e) {}
			//finally { } 
		}
		buf[count] = el;
		count++;
		
		if(count == 1)
			notify();
	}

	synchronized public int PobierzElement()
	{
		int temp;
		
		if(count == 0)
		{
			try 
			{ 
				wait(); 
			} 
			catch(Exception e) {}
		}
		
		temp = buf[count];
		count--;
		
		if(count == 9-1)
			notify();
		
		return temp;
	}
}

public class Zadanie
{
	public static void main(String args[])
	{
		Bufor04 bufor = new Bufor04();

		new Thread(new Producent(bufor)).start();
		new Thread(new Konsument(bufor)).start();
	}
}


class Producent implements Runnable
{
	private Bufor04 bufor;

	Producent(Bufor04 _bufor)
	{
		bufor=_bufor;
	}

	public void run()
	{
		System.out.println("uruchomiony watek producenta");
		while(true)
		{ 
			bufor.WstawElement(1);
			System.out.println("wstawiono cos: count= " + bufor.count );

			try 
			{
				Thread.currentThread().sleep(100);
			} 
			catch(InterruptedException e) {}    
		}
	}
}

class Konsument implements Runnable
{
	private Bufor04 bufor;

	Konsument(Bufor04 _bufor)
	{
		bufor=_bufor;
	}

	public void run()
	{
		System.out.println("uruchomiony watek konsumenta");
		while(true)
		{
			int j=bufor.PobierzElement();
			System.out.println("skonsumowano: count= " + bufor.count );


			try 
			{
				Thread.currentThread().sleep(100);
			} 
			catch(InterruptedException e) {}
		}
	}
}

0
__krzysiek85 napisał(a)

Inna sprawa, że tu chyba pomyliłeś kolejność instrukcji.

 System.out.println("bylem w wait, ale sobie wyszedlem, czemu?" );
this.wait();

tak zgadza się, ale to nieistotny szczegół

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