2017-05-09 78 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