# Threads synchronisieren mit Pipes



## furchi (20. Mai 2006)

Hallo,

Seit längerem versuche ich verzweifelt zwei Threads über Pipes zu verbinden. 

Der erste Thread (producer) soll dazu verwendet werden RGB Werte eines ".jpg" Bildes von einem Server zu laden.
Die RGB Daten sind als Integer Werte in einem DataOutputStream verpackt. 
Der consumer Thread ist für die graphische Darstellung als BufferedImage zuständig, sollte also die Daten vom Producer weiterverarbeiten.
Um diese beiden Threads möglichst elegant zu synchronisieren, möchte ich Pipes verwenden.

Nun habe ich aber das Problem, dass die Daten beim producer zwar fehlerfrei ankommen, aber nicht vollständig über die Pipe laufen. Beim consumer Thread kommt nur ein Teil an.

hier die wesentlichen Codeteile:

BasisKlasse:

```
PipedOutputStream pout = new PipedOutputStream();
PipedInputStream pin = new PipedInputStream(pout); 

GetPicture prod = new GetPicture(ip, port, pout);
ShowPicture cons = new ShowPicture(pin);
			
prod.start();
cons.start();
```

ProducerThread:

```
public class GetPicture extends Thread {
	private DataOutputStream out;
	private DataInputStream in;
	private Socket socket = null;
	private String ip = "";
	private int port = 0;

	public GetPicture(String ip, int port, OutputStream out) {
		this.ip = ip;
		this.port = port;
		this.out = new DataOutputStream(out);

		try {
			socket = new Socket(ip, port);
			in = new DataInputStream(socket.getInputStream());
		} catch (Exception e) {
			System.out.println("GetPicture " + e.getMessage());
		}

	}

	public void run() {
		try {
			while (in.available() > 0) {
				out.write(in.readInt());
			}
			// in.close();
			// socket.close();
			// pout.close();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}

	}

}
```

ConsumerThread:

```
public class ShowPicture extends Thread {
	private DataInputStream in;
	// private ImageFrame target;

	public ShowPicture(InputStream in) {
		this.in = new DataInputStream(in);
	}

	public void run() {
		// int width=0;
		// int height=0;
		int val;
		try {
			while (in.available() > 0) {
				val = in.readInt();
				System.out.println(val);
			}
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
}
```

Kann das Problem vielleicht an den DataOutput/InputStreams in Verbindung mit den PipedStreams liegen?

vielen Dank im Voraus
mfg


----------



## Beni (20. Mai 2006)

Also wenn der Consumer schneller als der Producer ist, dürfte "in.available" plötzlich mal = 0 sein.

"available" sagt nicht wieviele Bytes insgesammt gelesen werden können! Es sagt nur, wieviele Bytes *jetzt* gerade ganz schnell gelesen werden können.


----------



## foobar (20. Mai 2006)

Lass den Consumerthread doch mit wait() auf die Daten warten um ihn dann aus dem Producerthread mit notifyAll() aufzuwecken. Dann kannst du immer sicher sein, daß Daten vorhanden sind.


----------



## furchi (20. Mai 2006)

thx für die Antworten,

Die Funktion von in.available() ist mir klar, war nur für Testzwecke vorhanden. 
Warum die Piped Streams nicht richtig funktionieren ist mir immer noch ein Rätsel (wait(), notify() sind soweit ich weiß nicht notwendig, da die Pipes ja intern synchronisieren sollten). 

Jedenfalls habe ich das Problem jetzt mit einer eigenen Bufferklasse gelöst. 

mfg


----------

