# Einen HandlerThread, der mehrere Verbindungen verwaltet?



## uNiKoMpLeX (31. Mai 2005)

Hallo zusammen!

Habe da ein kleines Problem, dass mir aber eine Menge Kopfzerbrechen bereitet:
Ich benutze derzeit für jeden Client, der bereits erfolgreich eingeloggt ist und sich in einem Raum befindet einen eigenen Thread, der diese Verbindung verwaltet. Sollte die Verbindung gekappt werden, wird eine IOException ausgegeben.
Wenn man nun davon ausgeht, dass sich zu Stoßzeiten ungefähr 500 User im Chat aufhalten, steigt die Anzahl der Threads natürlich auch auf 500. Nun sind ja Threads nicht unbedingt Ressourcensparer und es ist nun ja auch nicht unbedingt schonend für die CPU, wenn sie ein Programm mit mehr als 500 Threads verwalten müsste.

Ich habe nun versucht, einen einzigen Thread damit zu beauftragen, alle Verbindungen zu verwalten (die Clientdaten werden über 'ne HashMap gespeichert). Durch einen Iterator holt sich nun dieser Thread zuerst die Client-Klasse und überprüft dann den in der Klasse befindlichen InputStream, ob noch eine Verbindung besteht (
InputStream in;
.
.
.
if((in.read())!=-1)...
.
.
.
)(wenn ja, ist die Verbindung noch erhalten, wenn nein, erzeugt der Thread eine IOException).
Nun wird aber die Schleife, die den Iterator ausliest, solange durch die read() Methode blockiert, bis die Verbindung des ersten Clients geschlossen wurde; danach wird erst der nächste überprüft und dort blockiert diese read() wieder....

Nun grübel ich schon die ganze Zeit, wie man dieses Problem am besten lösen kann, komme aber auf keine Antwort.
Mein Ziel wäre ein Thread, der überprüft, ob die Verbindung zu den Clients noch steht, aber ohne dass die Schleife solange blockiert, bis dieser Zustand für den ersten wirklich zutrifft.

Hätte jemand einen Vorschlag?
  :roll: 

Liebe Grüße
Daniel


PS: Hier der Source des Threads



```
import java.util.HashMap;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.Iterator;

public class Content extends Thread
{
    public static HashMap roomList=new HashMap(20),userList=new HashMap(50);

    public Content()
    {
        super("ContentThread");
        start();
        System.out.println("Content gestartet");
    }

    public void registerChannel(String id)
    {
        if(!roomList.containsKey(id))roomList.put(id,new Channel(id,false,true));
    }

    public void registerUser(String id,String nick)
    {
        if(!userList.containsKey(id))userList.put(id,new Client(id,nick));
    }

    public void deleteUser(String id)
    {
        if(userList.containsKey(id))userList.remove(id);
    }

    public void run()
    {
        Iterator it;
        Client cl=null;
        for(;;)
        {
            try
            {
                sleep(1000);
                it=userList.keySet().iterator();
                if(!userList.isEmpty())
                {
                    while(it.hasNext())
                    {
                        cl=(Client)userList.get((String)it.next());
                        if(cl.in.read()==-1)
                        {
                            System.out.println("Verbindung wurde unterbruchen");
                            deleteUser((String)cl.atr.get(0));
                            cl.close();
                        }
                    }
                }
            }catch(IOException e)
            {
                e.printStackTrace();
                deleteUser((String)cl.atr.get(0));
                cl.close();
            }catch(NullPointerException e11){/*ignore*/}
            catch(InterruptedException e1){/*ignore*/}
        }
    }
}
```


----------



## stev.glasow (1. Jun 2005)

erstmal:
mit aSocket.setSoTimeout(1000)  [serverseitig] kannst du verhindern, dass er beim Lesen nicht blockiert. In diesem Fall würde er eine java.net.SocketTimeoutException werfen wenn nach einer Sekunden nichts vom Client geschreiben wurde.

aber: warum machst du nichts mit den gelesen Daten? willst du nicht wissen was der Client geschrieben hat? 
Und die IOExceptions würde ich in der Schleife abfangen.

und: Weiß nicht ob wie du beschrieben hast 500 Thread zum Problem werden, aber einer wird es auf jeden Fall, denn selbst mit diesem SocketTimeout würde das Kommunizieren mit 500 Clients ewig dauern. Kannst du nicht pro Thread 10 Clients verwalten?


----------



## uNiKoMpLeX (1. Jun 2005)

ja eben genau dass möchte ich erreichen (x Clients durch einen Thread verwalten).

Die Anfrage wird bereits von einem Thread abgefangen und dort behandelt. Sollte sich User x nun einlogen wollen, erstellt der Server ein Clientobjekt mit den diversen Variablen, die dann im Chat benutzt werden sollen (ID, Farbe, Socket). Es wird die "Eingangs"-Seite an den Client geschickt und die ClientKlasse wird dann in der userList registriert. 

Somit hat der Thread nichts anderes zu tun als zu prüfen, ob die Verbindung überhaupt noch steht.
Danke für die Antwort, du hast mich gerade auf eine Idee gebracht 

Lg Daniel


----------

