2014-04-25 1 views
1

AsynchronousServerSocketChannel을 만들고 서버 소켓 소켓을 닫을 때까지는 아무 문제가 없습니다. 서버 및 모든 소켓 채널을 닫는 함수를 호출하는 특수 메시지를 사용하여 클라이언트에서 AsynchronousSocketChannel을 만듭니다. 서버가 닫혀 있지만 finnally 블록이 실행되지 않습니다. 이유가 무엇입니까?AsynchronousServerSocketChannel finally 블록이 실행되지 않았습니다.

확인 코드 :

public void openServerSocket(int sport) { 


    port = sport; 
    policyFile = createPolicy(new String[]{"*:"+port}); 
    try { 

     //group = AsynchronousChannelGroup.withThreadPool(Executors.newSingleThreadExecutor()); 
     //group.awaitTermination(1, TimeUnit.SECONDS); 
     server = AsynchronousServerSocketChannel.open(); 
     server.bind(new InetSocketAddress(sport)); 


     server.accept(null, this); 

     while(isOpen) { 

      //System.out.println("running server socket"); 

     } 
    }catch(Exception ex) { 
     this.message = ex.getMessage(); 
     System.out.println("Server: " + ex.getMessage()); 
    }finally { 

     System.out.println("Finall serversocket closing!"); 
     for(SocketHandler sh : sockets) { 
      sh.close(); 
     } 

     if(server != null) { 
      try { 
       server.close(); 
       server = null; 
      }catch(Exception ex2) { 
       this.message = ex2.getMessage(); 
      } 
     } 


     sockets.clear(); 
     sockets = null; 
     //this.message = "server socket closed"; 

     System.out.println("server socket down"); 
    } 

} 

@Override 
public void completed(AsynchronousSocketChannel socket, Void attachment) { 

    System.out.println("new connection"); 
    SocketHandler sh = new SocketHandler(socket, this); 

    server.accept(null, this); 
} 

@Override 
public void failed(Throwable exc, Void attachment) { 

    System.out.println("Server Failed accept:" + exc.getMessage()); 
} 


public void closeServerSocket() { 

    System.out.println("Closing server socket! " + server); 
    this.isOpen = false; 

} 

그래서 기능 closeServerSocket가 호출 내가 루프 유지 변수 ISOPEN false로 설정,하지만 난 ISOPEN var에 false로 설정하면 여전히 반복되는 동안 보인다 마지막으로 실행되지 않습니다입니까?

+1

'isOpen'은'false'로 변경됩니까? – JonK

+0

네, 변경되었지만 루프에 아무런 영향을주지 않습니다. 이유 : ( – user2803095

+0

'isOpen' 선언과 그 위치가 바뀔 수 있습니까? – JonK

답변

1

이 모양은 여러 스레드 간의 통신 문제처럼 보입니다. 코드에서 귀하의 while(isOpen) 루프가 closeServerSocket() 클래스와 다른 스레드에서 실행되는 것 같습니다. 이를 확인하려면 프린트 문에 Thread.currentThread()을 추가하십시오.

이 경우 isOpenvolatile으로 지정하여 문제를 해결할 수 있습니다. volatile이 없으면 다른 스레드가 쓰여진 값을 볼 수있는 경우 및 보장 할 수 없습니다. volatile을 사용하면 나중에 (벽시계 시간에 따라) 변수에 액세스하는 스레드에서 (내 해석 happens-before) 변경된 값이 표시됩니다.

volatile 대신 AtomicBoolean을 선호 할 수 있습니다.

+0

Ok 나는 테스트 해 보겠습니다. 에스. (server.isOpen()) 및 while (socket.isOpen()) 및 그 작업 동안, 나는 또한 스레드에 의해 당신의 제안을 테스트하고 알려주는 것이라고 생각합니다. – user2803095

+0

예 AtomicBoelan도 도움이되었으므로 개발자는 AtomicBoolean 또는 내부 루프 호출 socket.isOpen()을 사용하여 도움이되고 문제를 AtomicBoolean로 해결할 수 있습니다. 감사합니다 Harald – user2803095

관련 문제