gpt4 book ai didi

java - 在 Windows 上线程直到 Thread.join() 才停止

转载 作者:可可西里 更新时间:2023-11-01 11:47:20 26 4
gpt4 key购买 nike

方法 stopServer() 服务器在 Mac、Linux 和 UNIX 计算机上运行完美,但当我尝试在 Windows 上关闭时,我发现它至少需要一秒钟 每个 用于由于 ServerSocket 超时而关闭的套接字。我希望它们像在 Linux、Mac 等中那样一次关闭所有,而不是在我调用 Thread.join() 时一次关闭一个。

服务器代码

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");
}
}

为什么线程在退出 while 循环之前要求我加入它们?我已经测试并确定每个线程都在启动并且每个线程都被正确中断。

此外,如果我将 System.out.println() 放入 while 循环中,则只有一个线程会正确打印。

编辑

我非常清楚它必须等待 accept 超时。这是有意的,因此只有一秒钟的超时。这一切都可以在其他平台上正常运行。我正在中断所有线程然后加入它们以确保它们真正停止。我最担心的是为什么这些线程没有像它们应该的那样同时超时。

最佳答案

对于 *nix 操作系统,套接字实现不会在任何地方锁定 accept

对于 Windows,PlainSocketImpldefines accept as synchronized :

protected synchronized void accept(SocketImpl s) throws IOException {
// ...
}

accept 一次只被一个线程执行。 1 秒超时仅在最终获取锁后由 native accept 考虑。

我不知道这是不是故意的,你必须在 Java 邮件列表中询问。

关于java - 在 Windows 上线程直到 Thread.join() 才停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41841020/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com