Funktion sperren bis Unterfunktionen ferig sind

Excid

Mitglied
Hallo Community,

Ich habe folgenden Code.
Java:
private static int stopIndex=0;
static Vector<Server> Servers = null;
public static void Stop () {		
		System.out.println("Stopping...");
		stopIndex=Servers.size();
		while(stopIndex>0){
			Runnable R = new Runnable() {
				public void run() {

					Server C = Servers.get(stopIndex-1);
					System.out.println("Stopping server on port: " + C.getPort());
					synchronized(C) {
						if(C!=null)
							C.close();	
					}
					
					Servers.remove(C);
					
					C = null;
						
				}
					
			};
			Thread serverCloser = new Thread(R);
			serverCloser.start();
			stopIndex--;
		}
		Servers = null;
	}

Aktuell wenn ich Stop() ausführe werden, X Threads gestartet welche 10 Sekunden laufen.
X steht hier für die gestartet Server im Vector.
Sobald ein Server gestoppt wird, sendet dieser an alle seine Clients die Meldung das er in 10 Sekunden heruntergefahren wird.

Mein Problem. Wie schaffe ich es, das die Stop Funktion erst dann verlassen wird, wenn alle Threads fertig sind und Trotzdem alle Threads gleichzeitig laufen.
Das heisst das die ganze Aktion auch nur ~10 Sekunden dauert und nicht beispielsweise bei 10 Servern ganze 100 Sekunden.
Ah und aktuell wenn ich die Stop Funktion aufrufe, wird diese direkt verlassen und die Anwendung beendet.

Hmm ich bin unsicher ob ich das ganze "gut" beschrieben habe. Der Titel ist bestimmt auch nicht soooo super. Nur da ich nicht mal weiß ich nach der Lösung suchen soll, wüsste ich auch nicht wie ich es anders beschreiben kann ^^

Danke schon im voraus.

mfg Excid
 
Danke der Tipp war Super.

Hier die Lösung.

Danke 🙂

Java:
private static CountDownLatch stopLatch;
public static void Stop () {
		int stopIndex = 0;;
		System.out.println("Stopping...");
		stopIndex=Servers.size();
		stopLatch = new CountDownLatch(Servers.size());
		while(stopIndex>0){
			
			Runnable R = new Runnable() {
				public void run() {
					Server C = null;	
					synchronized (Servers) {

						C = Servers.get(Servers.size()-1);
						Servers.remove(C);
					}
					

					int p = C.getPort();
					System.out.println("Stopping server on port: " + p);
					synchronized(C) {
						if(C!=null)
							C.close();	
						System.out.println("Server on port: "+p+" stopped.");
					}
					
					C = null;
					stopLatch.countDown();	
				}
					
			};
			Thread serverCloser = new Thread(R);
			serverCloser.start();
			
			stopIndex--;
		}
		try {
			stopLatch.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Servers = null;
	}
 
Auch wenn die Methode "stop" verlassen wird, dürfte das ja noch nicht die Anwendung beenden. Bei mir funktioniert es jedenfalls auch ohne CountDownLatch:
Java:
import java.util.*;
import java.util.logging.*;

public class ThreadTest {

    private static int stopIndex = 0;
    static Vector<Server> servers = null;

    public ThreadTest() {
        servers = new Vector<Server>();
        for (int i = 0; i < 10; i++) {
            servers.add(new Server("port" + i));
        }
        for (Server server : servers) {
            Thread thread = new Thread(server);
            thread.start();
        }
        stop();
    }

    public static void stop() {
        System.out.println("Stopping...");
        stopIndex = servers.size();
        while (stopIndex > 0) {
            final Server server = servers.get(stopIndex - 1);
            Runnable close = new Runnable() {

                @Override
                public void run() {
                    System.out.println("Stopping server on port: " + server.getPort());
                    synchronized (server) {
                        if (server != null) {
                            server.close();
                        }
                    }
                }
            };
            Thread serverCloser = new Thread(close);
            serverCloser.start();
            servers.remove(server);
            stopIndex--;
        }
        servers = null;
        System.out.println("OK");
    }

    public static void main(String args[]) {
        new ThreadTest();
    }
}

class Server implements Runnable {

    private final String port;
    private boolean closed;

    public Server(String port) {
        this.port = port;
    }

    public String getPort() {
        return port;
    }

    public void close() {
        try {
            Thread.sleep(10000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
        }
        closed = true;
    }

    @Override
    public void run() {
        while (!closed) {
            try {
                Thread.sleep(300);
            } catch (InterruptedException ex) {
                Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        System.out.println(port + " now closed");
    }
}

Übrigens werden Methodennamen un Variablennamen immer klein geschrieben, Klassennamen dagegen immer groß.

Gruß,
André
 

Zurück
Oben