# Join von Threads bei I/O-Operation



## Chop (5. Aug 2006)

Hallo, 

ich hab hier einen Thread der die ganze Zeit auf Nachrichten vom Server wartet....  Wenn sich der Client jetzt nun abmeldet, möchte den Thread halt joinen um das alles zu beenden. Der Client schickt also dem Server eine Nachricht, dass er sich abmelden möchte und der Server schickt dem Client die Nachricht, dass das alles OK ist. Der Client empfängt die Nachricht und verarbeitet sie. Jetzt läuft allerdings der Thread wieder weiter und wartet auf eine neue Nachricht vom Server, da er das ganzer schafft bevor, der Client die nachricht verarbeitet und "isLoggedIn" auf false setzt. Dadurch blokiert er und joined nicht.

Wie löse ich das am besten? Ich möchte sehr ungern in dem ReceiveThread prüfen ob eine Antwort auf die Abmeldenachricht vom Server kommt.

Hier ist der Code des Threads:


```
public void run()
	{
		try{																	
			do
			{
				Message receivedMessage = receiveMessage();
				System.out.println("MESSAGE RECEIVED "+receivedMessage.getClass().getSimpleName());
				client.processMessage(receivedMessage);
				
			}while(client.isLoggedIn());
			
		}catch(IOException e){
			e.printStackTrace();
			}
		catch(ClassNotFoundException e){
			e.printStackTrace();
			}
	}
```


Vielen dank schonmal,

Gruß
Chop


----------



## moormaster (5. Aug 2006)

Trennt denn der Server nicht die Verbindung vom Socket, nachdem er die Abmeldung bestätigt hat? Das würde dann dazu führen, dass auch keine blockende Leseoperation auf der Clientseite mehr stattfindet, weil diese dann auch sofort mit einer Exception abgebrochen wird und voila: dein Thread kann sich in seiner while Schleife nochmals der Überprüfung der isLoggedIn Variable widmen 

Der Client könnte genauso gut nach empfangener Bestätigung vom Server das Socket schliessen und das Resultat wäre das gleiche.


----------



## Chop (5. Aug 2006)

ja, klar kann ich das machen. Ich dachte mir aber, dass es sauberer wäre wenn ich die Verbindung nicht einfach abbreche sondern dass beiden Seiten klar ist, dass die Verbindung geschlossen wird und dann dementsprechend die Streams geschlossen werden.

Ist das die übliche Vorgehensweise?


----------



## moormaster (5. Aug 2006)

Chop hat gesagt.:
			
		

> ja, klar kann ich das machen. Ich dachte mir aber, dass es sauberer wäre wenn ich die Verbindung nicht einfach abbreche sondern dass beiden Seiten klar ist, dass die Verbindung geschlossen wird und dann dementsprechend die Streams geschlossen werden.



Also wenn du an den Server die Anfrage zur Abmeldung schickst, der Server sein OK gesendet hat und du dann erst auf einer der beiden Seiten die Verbindung kappst: Ist das dann nicht eine Art Einverständnis beider Seiten?



> Ist das die übliche Vorgehensweise?



Ich kenne ich es so, dass der Server die Verbindung beendet und habe das bisher auch immer so umgesetzt.

Wenn man nicht gerade gute Gründe hat, die dagegen sprechen, so vorzugehen; Wieso sollte man es dann nicht so realisieren?


----------



## Chop (5. Aug 2006)

moormaster hat gesagt.:
			
		

> Also wenn du an den Server die Anfrage zur Abmeldung schickst, der Server sein OK gesendet hat und du dann erst auf einer der beiden Seiten die Verbindung kappst: Ist das dann nicht eine Art Einverständnis beider Seiten?



Ja, ist es. Ich müsste allerdings ein weiteres Flag im ReceiveThread setzen, damit dieser die verarbeitung der Nachricht abwartet oder ich muss im in dem Thread bereits überprüfen was für eine Nachricht denn da wirklich ankommt um dann entsprechend zu reagieren, wenn der Client sich abmeldet. Beides finde ich nicht so toll.....



			
				moormaster hat gesagt.:
			
		

> Ich kenne ich es so, dass der Server die Verbindung beendet und habe das bisher auch immer so umgesetzt.
> 
> Wenn man nicht gerade gute Gründe hat, die dagegen sprechen, so vorzugehen; Wieso sollte man es dann nicht so realisieren?



Tjoa, gute Frage. . Also ich denke, ich werde das dann auch so machen.... Ich dachte es gebe da vielleicht eine spezielle vorgehensweise, da man ja nicht explizit einen Thread terminieren kann. Die meisten Sachen die ich zu diesem Thema gefunden habe bezogen sich auf Threads, wo der Thread nicht innerhalb blokiert und dementsprechend immer wieder die while(condition) überprüft und dann dementsprechend den Thread selbständig beendet.


----------



## moormaster (5. Aug 2006)

Chop hat gesagt.:
			
		

> moormaster hat gesagt.:
> 
> 
> 
> ...



Mal ein Beispiel: Beim Internet Relay Chat (IRC) arbeiten die Server z.B. auch so, dass der Client einen QUIT Befehl sendet und der Server antwortet nach einer Zeit mit einer ERROR Nachricht darauf, welche signalisiert, dass der Server die Verbindung trennt, was er direkt darauf auch tut. Somit schlägt jeder Leseversuch im Thread sofort fehl ohne, dass der Thread wissen muss, dass der Server eine ERROR Message gesendet hat. Der Thread weiss höchstens, dass eine entsprechende Exception beim Leseversuch vom Socket aufgetreten ist und kann dann darauf basierend programmintntern noch eine Benachrichtigung absetzen, dass die Verbindung getrennt wurde.

So braucht der Thread nicht auf die Verarbeitung zu warten und bricht dennoch sofort bei Verbindungsende ab.

Wenn man sich nun noch merkst, ob man das Ende der Verbindung angefordert hat, kann man zwischen echten Verbindungsabbrüchen und dem Verbindungsende unterscheiden.


----------



## Chop (5. Aug 2006)

Jo, das ist doch mal ne schöne Lösung! So werde ich das dann auch bei mir implementieren......

Vielen Dank, hast mir echt geholfen!

Gruß
Chop


----------

