Die Methode stopServer()
der Server funktioniert einwandfrei auf Mac, Linux und UNIX-Computern, aber wenn ich versuche, unter Windows zu schließen, finde ich, dass es mindestens eine Sekunde dauert jeweils für die Sockets zu schließen wegen der Zeitüberschreitung der ServerSocket
. Ich möchte, dass sie alle auf einmal geschlossen werden, so wie sie es unter Linux, Mac usw. tun, im Gegensatz zu einem, wenn ich unter Thread.join()
anrufe.Thread nicht bis Thread.join() unter Windows
Server-Code
public class FileServer {
private ArrayList<Thread> sockets = new ArrayList<>();
private ServerSocket fileServer;
public void startServer(int port, int maxThreads, int timeout) throws IOException {
fileServer = new ServerSocket();
fileServer.setPerformancePreferences(1, 0, 1);
fileServer.bind(new InetSocketAddress(port));
for (int threads = 0; threads < maxThreads; threads++) {
sockets.add(new Thread(new ServerInit(fileServer, timeout)));
System.out.println("Socket " + threads + " initialized...");
}
for (int socket = 0; socket < sockets.size(); socket++) {
(sockets.get(socket)).start();
System.out.println("Socket " + socket + " started!");
}
}
public void stopServer() {
if (fileServer.isBound()) {
for (int thread = 0; thread < sockets.size(); thread++) {
sockets.get(thread).interrupt();
}
for (int thread = 0; thread < sockets.size(); thread++) {
try {
if (sockets.get(thread).isAlive()) {
sockets.get(thread).join();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
class ServerInit implements Runnable {
private ServerSocket server;
private int timeout;
public ServerInit(ServerSocket server, int timeout) {
this.server = server;
this.timeout = timeout;
}
public void run() {
while (!Thread.interrupted()) {
try {
server.setSoTimeout(1000);
Socket client = server.accept();
client.setSoTimeout(timeout);
processRequest(receiveRequest(client), client);
client.close();
} catch (SocketTimeoutException ste) {
} catch (IOException io) {
io.printStackTrace();
}
}
System.out.println("Socket closed");
}
}
Warum ist es, dass die Fäden erfordern mich ihnen anzuschließen, bevor sie die while
Schleife verlassen wird? Ich habe getestet und bin sicher, dass jeder Thread startet und dass jeder Thread ordnungsgemäß unterbrochen wird.
Auch nur ein Thread wird ordnungsgemäß gedruckt, wenn ich System.out.println()
in die while
Schleife legen.
EDIT
Ich bin viel mehr als bewusst, dass es für accept
Timeout warten. Das soll also nur eine 1 Sekunde Timeout sein. Dies alles funktioniert perfekt auf anderen Plattformen. Ich unterbreche alle Threads und schließe mich ihnen an, um sicherzustellen, dass sie tatsächlich aufhören. Meine größte Sorge ist, warum diese Threads nicht zeitgleich ausgeführt werden, wie sie sein sollten.
Wie genau stellst du dir das vor? Der Thread ist in "accept", es wird unterbrochen. Denken Sie, dass eine InterruptedException ausgelöst wird? Per Konvention löscht das Interrupt-Flag, was alles ist, was Sie überprüfen. –
Es gibt nichts im Javadoc, das besagt, dass "ServerSocket.accept()" unterbrechbar ist, also warten alle Ihre Threads auf das akzeptierte Zeitlimit. Ihr Code funktioniert wie vorgesehen. Interessant, dass es auf manchen Plattformen schneller ist, aber es ist nichts falsch daran, wie es unter Windows läuft. Dein Titel ist bedeutungslos. – EJP
Warum nicht eine flüchtige statische Variable (Semaphor) in der while-Schleife der 'ServerInit'-Klasse verwenden, um die Threads zu stoppen, anstatt das Interrupt-Flag zu prüfen? –