try (ServerSocket listenSocket = new ServerSocket(port)) {
log.info("Web Application Server started {} port.", port);
// 클라이언트가 연결될때까지 대기한다.
Socket connection;
// while문이 종료가 안되는 이유는 ?
while ((connection = listenSocket.accept()) != null) {
RequestHandler requestHandler = new RequestHandler(connection);
requestHandler.start();
}
}
이 코드에서 while 문이 종료되지 않는 이유는 listenSocket.accept() 메서드 때문입니다.
listenSocket.accept() 메서드는 클라이언트의 연결 요청을 기다리는 블로킹 메서드입니다. 이 메서드는 클라이언트의 연결 요청이 들어올 때까지 계속 대기하게 됩니다.
따라서 while 문 내부에서 listenSocket.accept() 메서드가 호출되면, 클라이언트의 연결 요청이 들어올 때까지 무한정 대기하게 됩니다. 클라이언트가 연결을 요청하면 accept() 메서드가 반환되고, 그때 while 문의 다음 반복이 실행됩니다.
<aside> <img src="/icons/info-alternate_blue.svg" alt="/icons/info-alternate_blue.svg" width="40px" /> 블로킹 메서드(Blocking method)란?
메서드 호출 시 작업이 완료될 때까지 스레드가 대기하는 메서드를 말합니다.
블로킹 메서드의 특징은 다음과 같습니다:
작업 완료 전까지 스레드가 대기하게 됩니다.작업이 완료되면 결과를 반환하거나 예외를 던집니다.호출한 스레드는 다른 작업을 수행할 수 없게 됩니다.
**논블로킹 메서드(Non-blocking method)**는 작업이 완료되지 않더라도 즉시 반환되는 메서드입니다. 논블로킹 메서드를 사용하면 스레드가 다른 작업을 수행할 수 있게 되어 효율적인 프로그래밍이 가능합니다.
</aside>
이 코드에서는 클라이언트의 연결 요청을 멀티스레딩으로 처리하고 있습니다.
while 문 내부에서 listenSocket.accept() 메서드가 호출되면, 클라이언트의 연결 요청이 들어올 때마다 새로운 Socket 객체가 생성됩니다.
accept() 메서드를 요청하면 다음과 같은 일이 발생합니다첫 번째 클라이언트의 연결 요청이 들어오면 accept() 메서드가 해당 연결을 반환합니다.
두 번째 클라이언트의 연결 요청이 들어오면 accept() 메서드가 해당 연결을 반환합니다.
이런 식으로 10명의 클라이언트 연결 요청이 모두 처리될 때까지 accept() 메서드는 대기하고 있다가 각각의 연결을 반환합니다.
이때 중요한 점은 accept() 메서드가 블로킹 메서드라는 것입니다. 즉, 첫 번째 클라이언트의 연결이 반환되기 전까지는 다른 클라이언트의 연결 요청을 처리할 수 없습니다.