线程不会停止,直到Windows上的Thread.join()

stopServer()服务器在Mac,Linux和UNIX计算机上完美工作,但是当我尝试在Windows上closures时,我发现由于ServerSocket的超时, 每个套接字要closures至less需要一秒。 我想让他们像在Linux,Mac等一样closures所有,而不是在我调用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"); } } 

为什么线程要求我在joinwhile循环之前join它们? 我已经testing并确信每个线程都正在启动,并且每个线程都被正确中断。

此外,只有一个线程将打印正确,如果我把System.out.println()在循环。

编辑

我更意识到,它必须等待accept超时。 这是打算,因此只有一秒超时。 这一切在其他平台上完美运作 。 我正在中断所有的线程,然后join他们,以确保他们实际上停止。 我最关心的是为什么这些线程不能同时按照它们的时间同步。

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

对于Windows, PlainSocketImpl类将accept定义为synchronized

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

accept是一次只能由一个线程执行的。 在最终获取锁之后,1秒超时仅由本地accept计入。

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