Threads blocken

rand0m

Mitglied
Hi.

Leider eine extreme Anfängerfrage zu der ich einfach keine Lösung find:
Wie starte ich 2 Threads ohne dass mein ganzes Programm wegen dem 1. "hängt".

Bsp.:
Code:
new ClientThread(serverSocket.accept(), this).start();  
new ClientDataThread(5999).start();

die 2 new Threads hab ich als eigene Klassen geschrieben.
Aber da ein Thread den anderen Blockt komm ich gar nicht erst zum 2.

ich :(

lg
 
Hi,

an Deiner Frage sind auch schon Nichtanfänger verzweifelt ;-) also ist schon ok.

Guck Dir mal Semaphore an: http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Semaphore.html

Man kann auch ohne Semaphore ein Thread Scheduling machen, aber so ist es am unkompliziertesten. Der Semaphore sorgt dafür, dass jeder Thread zu seinem Recht kommt.
So wird das Verhungern von Threads verhindert.

Bei eigenen Implementationen, die "synchronized" benutzen können, besteht das Risiko von Deadlocks, es ist aber eine Alternative. Mit synchronized Methoden oder Attributen bekommt jeder Thread einen eigenen Monitor. Benutzt man normalerweise um zu verhindern, dass zwei oder mehr Threads auf dieselbe Ressource gleichzeitig zugreifen.

Für ein einfaches Scheduling wie Du es brauchst, ist Semaphore schnell und unkompliziert.

Du könntest eine Warteschlange auch selbst bauen, packst die Threads in eine Liste
und gibst jedem Thread ein Zeitintervall um zu agieren, schläferst ihn dann ein und n immst den nächsten dran. Hier könntest Du selbst (als Lerneffekt) Betriebssystem Algorithmen ausprobieren (Last In – First Out out etc...).

Wenn ich Zeit finde, poste ich nochmal Beispielcode (am WE evtl.).

Grüßr, Tim
 
So, in deiner Main Klasse muss es einen Semaphore geben, den jeder Thread
übergeben bekommen muss:

Code:
private static final Semaphore semaphore = new Semaphore(5, true);

5 bedeutet, der Semaphore lässt 5 Threads gleichzeitig rein.
der Parameter true ist der Fairness Parameter. Er garantiert, dass jeder Thread
zu seinem Recht kommt.

Innerhalb deiner Thread Klasse (z.B. MyJob) hast Du ja eine Methode,
die er bei Aufruf von "run()" ausführen soll.

Code:
public void work() throws InterruptedException{			
	//aquire & release would enable this thread to run eternally,
	//or until this method was finished
		
			getSemaphore().acquire();
			
                        int n=0;
			while(n < 1000){//do job eternally				
				System.out.println( getName() );				
			}

			getSemaphore().release();
		
	}

getSemaphore() sollte natürlich den Semaphore liefern.

So hast Du alle Threads (im Beispiel 5) gleichmäßig am Laufen.

Grüße, Tim
 
Ein Thread ist von sich aus nebenläufig, das heißt du brauchst keine Semaphore um zwei Threads gleichzeitig laufen zu lassen.
Ein Semaphor ist ein Instrument zur Synchronisation mehrerer Threads, bewirkt also genau das Gegenteil.

Ich würde eher darauf tippen, dass was in den beiden Thread-Klassen falsch verstanden wurde. Kannst du mal Beispielcode posten?
 
Hab mir deinen Code nochmal angesehen

new ClientThread(serverSocket.accept(), this).start();
new ClientDataThread(5999).start();

Das Problem ist dass du dem Client-Thread schon serverSocket.accept() übergeben willst. die accept Methode blockiert aber. Noch bevor der Thread überhaupt erstellt wird blockiert das ganze. Das Problem ist also nicht der Thread an sich sondern dein Hauptprogramm.

Die Lösung wäre serverSocket zu übergeben und das accept in der run-Methode des Threads auszuführen.
 
Threads sind von sich aus nebenläufig, das stimmt.

Aber: das Scheduling wird in Java 5 von der JVM, in Java 1.4 vom Betriebssystem durchgeführt.

D.h. die Threads sind NICHT garantiert nebenläufig/gleichberechtigt.
Threads könne verhungern.

Wenn Deine JVM oder Betriebssystem meint, ein Thread braucht mehr Ressourcen als der andere und dann bekommt er die auch.

Lässt Du 2 Threads unendlich hochzählen (probiers mal aus), kommt Nr. 2 nie mehr an die Reihe.

Daher brauchst Du auf jeden Fall Semaphore für ein Scheduling (oder die von mir geschilderten synchronized Geschichten), alleine um ConcurrentModificationExceptions zu vermeiden. ;-) und auch, damit alle Threads gleichberechtigt und nicht willkürlich dran kommen.

Als Entwickler wünscht man sich oft eine Kontrolle über diese Dinge, anstatt
die JVM oder das Betriebssystem Sachen machen zu lassen, die man nicht möchte...

Die Aquire und Release methoden sind da, um den Thread einen Block ausführen zu lassen, wenn er drankommt, und zwar bis zum Ende. Diese methoden verhindern sehr wohl, wie Cojote andeutet, dass ein anderer Thread dazwischenfunkt.

Grüße, Tim
 
Zuletzt bearbeitet:
Hab mir deinen Code nochmal angesehen

new ClientThread(serverSocket.accept(), this).start();
new ClientDataThread(5999).start();

Das Problem ist dass du dem Client-Thread schon serverSocket.accept() übergeben willst. die accept Methode blockiert aber. Noch bevor der Thread überhaupt erstellt wird blockiert das ganze. Das Problem ist also nicht der Thread an sich sondern dein Hauptprogramm.

Die Lösung wäre serverSocket zu übergeben und das accept in der run-Methode des Threads auszuführen.

Sorry tim ich hab zu wenig zu dem Problem gesagt, ich glaub dass was ich eigentlich suche ist Cojotes Lösung.
-Ich hatte im ClientThread aber alles mögliche stehen, dass jetzt dank dem accept, dass jetzt im Thread bei der run Methode steht, nicht lauft bzw. drannkommt?.
Sprich der Server baut sich auf aber wenn ich mit dem Client connecte passiert nichts..auch keine Exceptions bzw. konnte ich vorher beim Client schreiben und jetzt hängt er total.

+beide Threads scheinen jetzt zu laufen da ich von beiden eine Meldung bekomme

lg
 
Ich habe nicht so ganz verstanden ob sich das Problem erledigt hat oder ob nochwas hängt. Falls ja kannst du mal ein wenig Code posten?
 
Wow okey sorry, ich hab einen sehr dummen Fehler beim öffnen / createn des Serversockets gemacht.
Also die accept() in die run() Methode zu packen war die Lösung.
Nur schaff ichs jetzt nicht mehr dass mehrere Client auf den Server zugreifen können.
Ein Client kann und dann kein weiterer.
Ich muss .accept() in eine Schleife packen denk ich mal nur will das auch nicht funktionieren.
->
Code:
  public ClientThread(ServerSocket serverSocket,Server server) throws IOException {
	super("ClientThread");
	this.serverSocket = serverSocket;
	this.server = server;
    }

        public void run() {
  
        try{
        	
              	Socket socket =	serverSocket.accept();
        	                    
        this.out = new PrintWriter(socket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
				new InputStreamReader(
				socket.getInputStream()));
 

Neue Beiträge

Zurück