Synchronisation (notify, notifyAll, wait)

nighty86

Mitglied
Hallo,

Ich arbeite hier an einem kleinen Programm (BoundedCounter), welcher einen Zähler hat, mit dem ich anhand von Threads hoch und runter zähle. Im Konstruktor geb ich dann ein Maximum und Minimum an...

Hier erstmal der Code :

Java:
package fopt.assignment1;



public class BoundedCounter 
{

		public static void main(String[] args)
		{
			BoundedCounter counterX = new BoundedCounter(0, 5);

			for(int i = 1; i <=3; i++)
			{
				new up(counterX);
				new up(counterX);
				new up(counterX);
				new down(counterX);
				new down(counterX);
				new down(counterX);
			}
			
		}



	
	private int zaehler, MaxWert, MinWert;
	public BoundedCounter(int MinWert, int MaxWert)
	{
	if (MinWert>MaxWert || MinWert == MaxWert)
		throw new IllegalArgumentException();
	this.MaxWert = MaxWert;
	this.MinWert = MinWert;
	this.zaehler = MinWert;
	}
	
	public synchronized void up()
	{
		while (zaehler == MaxWert)
			try
		{
			wait();
		}
		catch(InterruptedException e)
		{		
		}
		while((zaehler < MaxWert))
		{
			zaehler++;
			System.out.print(" ");
			System.out.print(get());
		}
		notifyAll();
		

			
		}
	
	public int get()
	{
		return zaehler;
	}
	
	
	public synchronized void down()
	{
		while (zaehler == MinWert)
			try
		{
			wait();
		}
		catch(InterruptedException e)
		{		
		}
		while((zaehler > MinWert))
		{		
			zaehler--;
			System.out.print(" ");
			System.out.print(get());
			
		}
		notifyAll();
		
	}

	public int getZaehler() {
		return zaehler;
	}

	public void setZaehler(int zaehler) {
		this.zaehler = zaehler;
	}

	public int getMaxWert() {
		return MaxWert;
	}

	public void setMaxWert(int maxWert) {
		MaxWert = maxWert;
	}

	public int getMinWert() {
		return MinWert;
	}

	public void setMinWert(int minWert) {
		MinWert = minWert;
	}
}
	
class up extends Thread
	{
		private BoundedCounter counter;
		public up(BoundedCounter counter)
		{
			
			this.counter = counter;
			start();
		}
	
		

		public void run()
		{		
			counter.up();				
		}
		
		
	}

	class down extends Thread
	{
		private BoundedCounter counter;
		public down(BoundedCounter counter)
		{
			
			this.counter = counter;
			start();
		}
		

		public void run()
		{
			counter.down();		
		}
		
		
	}

Scheint auch richtig zu funktionieren, jedoch krieg ich beim Bewertungssystem folgendes :

Unit Test - Test des korrekten Inkrementierens bzw. Dekrementierens
Dieser Testabschnitt prüft, ob sich die Komponente beim Inkrementieren des Zählwertes durch die Methode up() bzw. beim Dekrementieren des Zählwertes durch die Methode down() korrekt verhält. Als Basis für diesen Testabschnitt diente ein Minimum von 0 und ein Maximum von 5.
Beschreibung Unit-Test: get() liefert korrekten Wert nach einmaliger Erhöhung des Z&aumlhlers (vom Minimum ausgehend).
Testaufruf: m.get();

Fehler während Ausführung:
# Prüfung Rückgabewert fehlgeschlagen (erwartet: 1, zurückgegegeben: 5)!
Liveness Test Fehlgeschlagen: Ein oder mehrere Threads waren am Ende der Sequenz noch aktiv.
Mögliche Ursache: Thread verklemmt (Deadlock), Endlosschleife oder wait() ohne notify()

Hat da vielleicht jemand eine Idee? Und kann mir vielleicht erklären was ich falsch gemacht habe? Und warum das falsch ist? Ich finde es grad nämlich garnicht... :noe:

Danke erstmal im voraus :)
 

Marco13

Top Contributor
Hm. Der Wert, den der Counter am Ende hat, ist ziemlich "zufällig". (Submitte es einfach noch ein paar mal, irgendwann wird er schon den erwarteten Wert erwischen :lol: )

EDIT: Wobei das "Ende" auch ein bißchen schwierig zu definieren ist: Er sagt ja auch, dass noch ein Thread läuft, der nicht mehr laufen sollte. Ggf. muss man die ganzen Threads am Ende noch "join()"en, beschreib' ggf. mal die Aufgabenstellung genauer...
 

nighty86

Mitglied
Guten morgen,

Danke erstmal!
Ich werde es mal probieren "join" einzubauen. Hab da aber leider noch nicht so richtig den Durchblick was das genau macht...

Die Aufgabenstellung ist folgende :

Eine Klasse "BoundedCounter", der hat ein Konstruktor welcher zwei Werte in der Signatur hat. Ein Minimum, und ein Maximum. Dann sollte dieser eben up und down Methoden haben, sowie eben die ganzen get und set Methoden. Und halt der Zaehler als Variable. Die Aufgabe soll dann anhand von jeweils drei Threads (up und down) hoch und runterzählen, jeweils aber immer nur das max und minimum erreichen.
 

nighty86

Mitglied
Es funktioniert jetzt. Ich hatte einen richtig dämlichen Fehler drin.

Java:
 public synchronized void down()
    {
        while (zaehler == MinWert)
            try
        {
            wait();
        }
        catch(InterruptedException e)
        {       
        }
        if((zaehler > MinWert))
        {       
            zaehler--;
            System.out.print(" ");
            System.out.print(get());
            
        }
        notifyAll();

So müssen die up und down Methoden aussehen. Also, anstatt while muss ich if nutzen. :)
Außerdem muss die get() Methode synchronized sein...
Danke aber nochmal!
 

Neue Themen


Oben