2017-05-09 120 views
0

我有一个经典的服务器多客户端程序。服务器侦听ServerSocket并为每个传入的套接字构建一个新的Runnable类并在ExecuteService中执行它。Java尝试与资源卡住

在Runnable类的run方法中,我打开try-with-resources块,在try中我有一个while循环,它从inputstream中读取并写入outputstream,直到它从客户端接收到FIN命令。一切正常,客户端断开连接成功。运行到达finally块并打印一些东西进行测试,但它不会退出try块,因此它不会退出run方法,并且我被困在运行的某处,可能是inputstream的读取方法。

如果有人感兴趣,我可以发布代码。

如何强制关闭最后的所有内容并退出运行方法?

的代码:
Server.java:

public static void main(String[] args) { 
    playersReady = new ArrayList<Integer>(); 
    ServerSocket server = null; 
    try { 
     server = new ServerSocket(Consts.PORT); 
     ExecutorService service = Executors.newFixedThreadPool(characters.size()); 
     while(playersReady.size()<characters.size()){ 
      RequestHandler handler = new RequestHandler(server.accept()); 
      service.execute(handler); 
     } 
     service.shutdownNow(); 
     service.shutdown(); 
     while(!service.isTerminated()){} 

     System.out.println("finished"); 

RequestHandler.java

public final class RequestHandler implements Runnable { 

    ..... 

public void run() { 
    //DataOutputStream output = null; 
    //DataInputStream input = null; 

    try (DataOutputStream output = new DataOutputStream(socket.getOutputStream()); 
      DataInputStream input = new DataInputStream(socket.getInputStream())){ 
     // socket.setSoTimeout(500); 
     handleReady(input.readUTF().split(" "), output); 
     while (/*!shutdown && !socket.isClosed() && */socket.isConnected()) { 

      System.out.println("check before read " + character.getId()); 
      String request = input.readUTF(); 
      System.out.println("check after read " + character.getId()); 

      System.out.println("-----------------------------------" + request); 
      if (shutdown) { 
       socket.shutdownInput(); 
       socket.getOutputStream().flush(); 
       socket.shutdownOutput(); 
       break; 
      } 
      String[] requestParser = request.split(" "); 
      if (requestParser[1].equals("DMG")) { 
       // handle damage request 
       handleDamage(requestParser, output); 
      } else if (requestParser[1].equals("BND")) { 
       // handle bandage request 
       handleBandage(requestParser, output); 
      } else if (requestParser[1].equals("FIN")) { 
       // handle finish request 
       handleFin(); 
       if (!socket.isClosed()) 
        socket.shutdownInput(); 
       if (!socket.isClosed()) { 
        socket.getOutputStream().flush(); 
        socket.shutdownOutput(); 
       } 
       shutdown = true; 
       break; 
      } else { 
       break; 
      } 
     } 
    } catch (SocketTimeoutException e) { 
     System.out.println(e.getMessage()); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     shutdown = true; 
     break; 
    } catch (Throwable e) { 
     e.printStackTrace(); 
    } finally { 
     try { 
      System.out.println("finished"); 

      if (!socket.isClosed()) 
       socket.shutdownInput(); 
      if (!socket.isClosed()) { 
       socket.getOutputStream().flush(); 
       socket.shutdownOutput(); 
       socket.close(); 
      } 
      socket.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
    System.out.println("Done run"); 
} 

....


System.out.println("finished")在最后打印, 但System.out.println("Done run")在运行方法的结束不!

为什么?
它卡在run方法中,我想在readUTF调用中,但是我关闭了所有的资源!

+1

你有没有试过调试你的程序?你的“我认为在readUTF调用中”有点含糊。 – f1sh

+0

我试过了,没什么特别的,它传递run方法并上到java的Runnable类并停止,但线程继续运行 – faris

回答

3

您在该行之前返回,这就是为什么它没有运行。无论如何,finally块是运行的,因为它是一个最后的块。最后块总是运行,这个规则只有一个例外:System.exit(),但事实并非如此。

+0

什么行?运行方法运行完美,它只是不停止,并不会停止相关线程 – faris

+0

哦,我看到了,我将每个“返回”语句更改为“中断”。它现在打印最终的打印命令,但线程不停止,我的意思是它不会继续服务器的运行方法 – faris