Java 为什么thread.join()在windows上的行为如此不同?
我正在运行一个服务器并生成多个线程以允许多个套接字。显然,我希望能够在命令下关闭所有套接字。我为我的服务器编写了一个启动和停止函数,除非我在Windows上运行它,否则它几乎可以立即工作 启动/停止Java 为什么thread.join()在windows上的行为如此不同?,java,windows,multithreading,sockets,Java,Windows,Multithreading,Sockets,我正在运行一个服务器并生成多个线程以允许多个套接字。显然,我希望能够在命令下关闭所有套接字。我为我的服务器编写了一个启动和停止函数,除非我在Windows上运行它,否则它几乎可以立即工作 启动/停止 public void startServer(int port, int maxThreads, int timeout) throws IOException { fileServer = new ServerSocket(); fileServer.setPerformanc
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 {
sockets.get(thread).join();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
问题是,由于阻塞超时,每个线程都需要一秒钟的时间才能停止,但是,这只发生在Windows上。为什么Windows的表现如此不同,我应该如何着手解决这个问题
编辑
每个套接字都有一秒钟的超时。我意识到,这样做会导致每个套接字超时一秒钟,因此关闭,但为什么Windows为每个连接的线程花费一秒钟,而不是总共花费一秒钟的时间?您可以向我们展示
ServerInit
(或者至少是服务器线程的MVP)的代码吗?我的猜测是,Java正在等待(本机)系统调用返回,然后抛出中断的异常。但是可能是ServerInit
中的代码做了一些有趣的事情。我刚刚编辑了这个问题以包含ServerInit
代码。这可能是另一个问题的重复,其中,答案建议从另一个线程调用ServerSocket#close
,通过触发SocketException
来发出退出ServerSocket#accept
中阻塞的线程的信号。你确定问题在那里而不是在事情的中断端吗?我建议您添加大量带有时间戳的日志记录,以准确查看问题所在。@ChrisNauroth由于我的ServerSocket
实例的范围,我无法调用ServerSocket.close()
,但我可能错了。Jon,它在macos和linux发行版上运行得非常好。你能给我们看一下ServerInit的代码吗(或者至少是服务器线程的MVP)?我的猜测是,Java正在等待(本机)系统调用返回,然后抛出中断的异常。但是可能是ServerInit
中的代码做了一些有趣的事情。我刚刚编辑了这个问题以包含ServerInit
代码。这可能是另一个问题的重复,其中,答案建议从另一个线程调用ServerSocket#close
,通过触发SocketException
来发出退出ServerSocket#accept
中阻塞的线程的信号。你确定问题在那里而不是在事情的中断端吗?我建议您添加大量带有时间戳的日志记录,以准确查看问题所在。@ChrisNauroth由于我的ServerSocket
实例的范围,我无法调用ServerSocket.close()
,但我可能错了。Jon,它在macos和linux发行版上运行得非常好。
class ServerInit implements Runnable {
private ServerSocket server;
private int 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");
}
}