Nebenläufigkeit - Aufgabenstellung

Status
Nicht offen für weitere Antworten.
G

Guest

Gast
Hab hier diese Aufgabenstellung:

Schreiben Sie eine Klasse für einen Briefkasten. Das ist eine Warteschlange, in der man jederzeit etwas
hineinlegen kann. Wenn man aber eine Nachricht braucht, muss man warten bis eine ankommt. Verwenden Sie
hierzu die Bibliotheksklasse ArrayList und die Primitive synchronized, wait() und notifyAll().

Nun bin ich mir nicht ganz im klare darüber ob die Klasse "Briefkasten" Runnable implementieren muss, kann ich wait und notifyAll überhaupt benutzen wenn ich Runnable nicht implementiere?

Mein erster Entwurf der Klasse seiht so aus:
Code:
public class Briefkasten 
{
	private ArrayList<Message> al;
	
	public Briefkasten ()
	{
		al = new ArrayList<Message>();
	}
	
	public synchronized void put(Message message)
	{
		if (message == null)
			throw new NullPointerException();
		
		al.add(message);
	}
	
	public synchronized Message getMessage() throws InterruptedException
	{
		if (al.isEmpty())
			return null;
		
		Message m = al.get(0);
		remove();
		
		return m;
	}
	
	private synchronized void remove()
	{
		al.remove(0);
	}


}

Das ganze soll dann später in einer Implementierung des "ziege, wolf, kohlkopf, bauer am fluss-problem" anwendung finden.
 

Murray

Top Contributor
Runnable brauchst Du nicht.

get sollte doch sicher warten, bis ein Eintrag da ist. Also erst prüfen, ob es einen Wert gibt; wenn ja -> zurückliefern; falls nein -> warten (bis notifyAll aufgerufen worden ist) und dann das erste Element aus der Liste entfernen und zurückliefern

Damit get nicht ewig wartet, müsste put dann natürlich auch noch notifyAll aufrufen.
 
S

SlaterB

Gast
synchronized, wait und notify haben nichts direkt mit Runnable zu tun,
der Briefkasten als Datenstruktur sollte nicht Runnable implementieren

die Akteure, die den Briefkasten verwenden, werden dann Threads sein,
 
G

Guest

Gast
ok danke soweit.

wie genau funktioniert das mit wait und notfiyAll.

Ich kann einen Thrad schlafen legen, aber wenn ich notifyAll aufrufe erreicht die information anscheinend nicht den wartenden Thread. Muss jetzt meine Aufrufende Klasse das ganze steuern und das notify senden oder wie kann ich einen thread im wait modus dazu bringen zu einem notifyAll eines anderen Threads zu reagieren.
 
S

SlaterB

Gast
> aber wenn ich notifyAll aufrufe erreicht die information anscheinend nicht den wartenden Thread

Begrüngung, Codebeispiel?
normalerweise gehts, wenn man alles richtig macht, z.b. das nofiyAll() auch genau an dem Monitor-Objekt aufzurufen, an welchem der andere Thread wartet,

die Lehrbuch-Beispiele sowie das Grundlagenwissen dazu sind dir bekannt?
 
G

Guest

Gast
etwas aus der Vorlesung und was ich so dazu gelesen, das mit dem Monitorobjekt hab ich so jetzt nicht implementiert bekommen...wusste ich nicht wie ich das machen soll.

hier mal die verwendung meines briefkasten (meine testklassen) - denke mein problem liegt hier und nich im briefkasten selbst. Wie müsste das mit einem steuerenden Objekt aussehen?

Code:
public class RunTest 
{
	
	public static void main(String[] args)
	{

		Thread t1 = new Thread(new GetMessage());
		Thread t2 = new Thread(new PutMessage());
		
		t1.start();
		t2.start();
	}

}

Code:
public abstract class SuperBriefkasten implements Runnable
{
	private Briefkasten bk;
	
	public SuperBriefkasten()
	{
		bk = new Briefkasten();
	}
	
	public void addMessage(Message m)
	{
		bk.put(m);
	}
	
	public Message getMessage()
	{
		try 
		{
			return bk.getMessage();
		}
		catch (InterruptedException e)
		{
			e.printStackTrace();
		}
		
		return null;
	}
	
	public void run() 
	{
		
	}


}

Code:
public class PutMessage extends SuperBriefkasten 
{
	public void run()
	{
		System.out.println("Schreibe Nachricht in Warteschlange: " + Message.FARMER_MOVING);
		super.addMessage(Message.FARMER_MOVING);
	}
	
}

Code:
public class GetMessage extends SuperBriefkasten implements Runnable
{
	
	public void run() 
	{
		super.getMessage();
	}

}
 
S

SlaterB

Gast
was genau war an den zwei 'Briefkasten NICHT Runnable'-Posts jetzt so undeutlich?

und PutMessage + GetMessage sollen nicht von Briefkasten erben,
sondern einen gemeinsamen Briefkasten verwenden,

auweia, bei den Kenntnissen so ein kompliziertes Thema,
zu synchonized & Co. steht noch gar nix da, solange kann es dann zumindest auch nicht falsch sein
 
G

Guest

Gast
ok, wenn man mal etwas distanz dazu kriegt ist es doch gar nicht mehr so schlimm wie vorhin.....

habs jetzt hinbekommen

Wo genau is der qualitative Unterschied zwischen diese 2 Varianten:

Code:
	public static void main(String[] args)
	{

		Briefkasten bk = new Briefkasten();
		
		synchronized (bk) 
		{
			
			Thread t1 = new Thread(new GetMessage(bk));
			Thread t2 = new Thread(new PutMessage(bk));
			
			t1.start();
			t2.start();
		}
	}

und

Code:
	public static void main(String[] args)
	{

		Briefkasten bk = new Briefkasten();

			Thread t1 = new Thread(new GetMessage(bk));
			Thread t2 = new Thread(new PutMessage(bk));
			
			t1.start();
			t2.start();
	}
 

Murray

Top Contributor
Anonymous hat gesagt.:
ok, wenn man mal etwas distanz dazu kriegt ist es doch gar nicht mehr so schlimm wie vorhin.....

habs jetzt hinbekommen
Echt? Sieht nicht so aus...

Anonymous hat gesagt.:
Wo genau is der qualitative Unterschied zwischen diese 2 Varianten:

Code:
	public static void main(String[] args)
	{

		Briefkasten bk = new Briefkasten();
		
		synchronized (bk) 
		{
			
			Thread t1 = new Thread(new GetMessage(bk));
			Thread t2 = new Thread(new PutMessage(bk));
			
			t1.start();
			t2.start();
		}
	}

und

Code:
	public static void main(String[] args)
	{

		Briefkasten bk = new Briefkasten();

			Thread t1 = new Thread(new GetMessage(bk));
			Thread t2 = new Thread(new PutMessage(bk));
			
			t1.start();
			t2.start();
	}
Wenn es keine anderen Code gibt, der - in einem anderen Thread - ebenfalls auf die gleiche Briefkasten-Instanz synchronisiert oder als synchronized deklarierte Instanz-Methoden an dieser Briefkasten-Instanz aufruft, dann gibt es da keinen Unterschied.
 
S

SlaterB

Gast
zum Start der Threads muss man eben nicht synchronisieren,
die können ruhig alle gleichzeitig und durcheinander erzeugt werden,
wichtig sind nur deren folgeträchtigen Aktionen im Briefkasten wie put und get
 

Murray

Top Contributor
... und bei put und get reicht es dann, die Methoden als synchronized zu deklarierend; einen synchronized-Block auf die Briefkasten-Instanz im verwendenen Code wirst Du nicht brauchen.
 
G

Guest

Gast
Ist das so richtig?

Code:
import java.util.ArrayList;

public class Briefkasten
{
	private ArrayList<String> al;
   
	public Briefkasten (){
		al = new ArrayList<String>();
	}
   
	public synchronized void putNachricht(String nachricht){
		if (nachricht == null)
			throw new NullPointerException();
      
		al.add(nachricht);
		System.out.println(
				"Es wurde folgender Brief eingeworfen: "
				+nachricht);
		notify();
	}
   
	public synchronized String getNachricht(){
		if (al.isEmpty()){
			try{
				wait();
			} catch(InterruptedException ie){}
		}
		
		String m = al.get(0);
		al.remove(0);
		System.out.println(
				"Sie haben folgenden Brief erhalten: "
				+m);
		return m;
	}
}

Code:
public class Go {

	public static void main(String[] args) {

	       Briefkasten bk = new Briefkasten();
 
	       Kunde kunde = new Kunde(bk);
	       Postbote postbote = new Postbote(bk);
	       
	       postbote.start();
	       kunde.start();
	}
}

Code:
public class Kunde extends Thread
{
	private Briefkasten bf;
 
	public Kunde(Briefkasten bf){
		this.bf = bf;
	}
 
	public void run(){
 
		while (true) {
				String brief = "Ich bin Brief Nummer "+
					(int)Math.round(Math.random()*100+1);
				bf.putNachricht(brief);

			try {
				Thread.sleep((int)(100*Math.random()));
			} catch (InterruptedException ie) {
				ie.printStackTrace();
			}
		}
	}
}

Code:
public class Postbote extends Thread
{
	private Briefkasten bf;
 
    public Postbote(Briefkasten bf){
    	this.bf = bf;
    }
 
    public void run()
    {
    	while (true) {
    		bf.getNachricht();

    		try {
    			Thread.sleep((int)(100*Math.random()));
    		} catch (InterruptedException ie) {
    			ie.printStackTrace();
    		}
    	}
    }
}
 
G

Guest

Gast
In Briefkasten#getNachricht sollte die Exception nicht einfach ignoriert werden. Ansonsten sieht das auf den ersten Blick ganz OK aus - funktioniert es denn?
 

Murray

Top Contributor
Oops - das eben war ich.
Eine Sache noch: von Thread abzuleiten ist meistens nicht notwendig; man kann ebensogut Runnable implementieren.
Code:
class X implements Runnable {
  public void run() {
    ...
  }
}

...


new Thread( new X()).start();
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Threads Nebenläufigkeit Java Basics - Anfänger-Themen 4
Alen123 Wie würdet ihr diese Aufgabenstellung lösen? Java Basics - Anfänger-Themen 18
N Widerspruch in Aufgabenstellung? Java Basics - Anfänger-Themen 2
F Wie implementiere ich diese Aufgabenstellung? Java Basics - Anfänger-Themen 16
F Aufgabenstellung genauer formulieren/verständlicher machen? Java Basics - Anfänger-Themen 10
A Unsicher bei Aufgabenstellung Java Basics - Anfänger-Themen 9
A Vererbung Hilfe bei einer Aufgabenstellung Java Basics - Anfänger-Themen 3
D Erste Schritte Hilfe bei Aufgabenstellung Java Basics - Anfänger-Themen 1
M Verbunde Aufgabenstellung Java Basics - Anfänger-Themen 6
N kleine get-Methode anhand einer Aufgabenstellung Java Basics - Anfänger-Themen 13
H Problem mit Aufgabenstellung Java Basics - Anfänger-Themen 3
B verständnisprobleme bei Aufgabenstellung Java Basics - Anfänger-Themen 25
M Gibt es eine einfachere Variante diese Aufgabenstellung zu lösen? Java Basics - Anfänger-Themen 11
J Rekursionsproblem/Aufgabenstellung Java Basics - Anfänger-Themen 9
J Erste OO-Aufgabe-Probleme mit Aufgabenstellung Java Basics - Anfänger-Themen 32
A aufgabenstellung tips Java Basics - Anfänger-Themen 7
M Zwei Lösungsvorschläge für eine Aufgabenstellung gesucht Java Basics - Anfänger-Themen 3
A verstehe aufgabenstellung nicht! Java Basics - Anfänger-Themen 47
E Klassen erkennen in einer Aufgabenstellung Java Basics - Anfänger-Themen 6
W Vererbung: Aufgabenstellung Java Basics - Anfänger-Themen 15
G Aufgabenstellung in JAVA, wie anfangen ? Java Basics - Anfänger-Themen 13

Ähnliche Java Themen

Neue Themen


Oben