2012-04-05 5 views
1

현재 여러 클라이언트가 연결할 서버를 작성하고 있습니다. 통신 프로토콜은 기본적으로 서버가 클라이언트에게 작업을 보내고 작업이 수행 될 때 클라이언트가 응답합니다. 클라이언트는 서버에 연결된 채로 끊어서는 안됩니다.서버 소켓 클라이언트 용 새 스레드 대신 Executor 사용

현재 각 클라이언트를 처리하기 위해 새 스레드가 시작됩니다. (Java Concurrency in practice에서 소스)

public class ThreadPerTaskWebServer { 
    public static void main(String[] args) throws IOException { 
     ServerSocket socket = new ServerSocket(80); 
     while (true) { 
      final Socket connection = socket.accept(); 
      Runnable task = new Runnable() { 
       public void run() { 
        handleRequest(connection); 
       } 
      }; 
      new Thread(task).start(); 
     } 
    } 

    private static void handleRequest(Socket connection) { 
     // request-handling logic here 
    } 
} 

그러나 그들은 더 안정적인 것 그리고 더 나은 확장 이후는 실행자를 사용하고 싶습니다 : 정신으로 내 현재 솔루션은 다음과 같이한다. 따라서 서버가 클라이언트에 메시지를 보낼 수 있으려면 클라이언트를 실행중인 Executor와 별도로 추적해야합니다. 이 날 모든 클라이언트와 명령을 전송하기 위해으로 CopyOnWriteArrayList 반복 할 수 있도록 할

Socket clientSocket = serverSocket.accept(); 
// The runnable that takes care of a client 
ClientHandler c = new ClientHandler(clientSocket, this); 
// Start executing the ClientHandler 
exec.execute(c); 
// Add clients to CopyOnWriteArrayList 
clients.add(c); 

: 내가 어디 다음으로 CopyOnWriteArrayList 클라이언트에서 클라이언트를 배치하고 경우에 따라서 서버 클래스에서이 같은 뭔가를 분리 된 것들을 제거하십시오. 이것이 강력한 해결책입니까? 어떤 이유로 Runnable이 예외를 전파한다면 Executor에서 어떤 일이 일어날까요?

+0

클라이언트와 서버가 혼합되어 있습니다. 귀하의 경우 클라이언트는 서버이며 반대의 경우도 마찬가지입니다. – ahanin

+1

@ahanin 나는 그것이 전체적으로 명확하지 않다는 데 동의하지만 이것은 * 가장 정확한 * 설명이라고 생각합니다. 클라이언트가 서버에 연결하고 ServerSocket이 있기 때문에 서버 정의가됩니다. – Teletha

+0

혼란스럽지 않습니다. 의도가 무엇인지 완전히 이해했습니다. 단지 @Teletha가 개념을 뒤섞고 있음을 지적하고 싶었습니다. 설명 된 경우 클라이언트는 작업 실행을위한 "서버"요청을 처리하는 일종의 작업자 에이전트입니다. – ahanin

답변

1

강력한 솔루션입니까?

예, 그렇게 생각합니다. 고정 된 크기의 풀에 적절한 수의 스레드를 할당하거나 동적 풀을 사용해야합니다.

어떤 이유에서든 실행 가능 파일이 예외를 전파한다면 실행 프로그램은 어떻게됩니까?

코드가 발생하면 RuntimeException 다음 중지되지만 풀 스레드 수가 감소 될 코드를 실행하는 실행 프로그램 풀 스레드와 서비스가 이미 종료되지 않은 경우 작성한 다른 스레드. 따라서 스레드 풀이 계속해서 적절하게 작동합니다. 이 날이 끊긴 사람

을 모든 클라이언트에 명령을 보내도 제거하기 위해으로 CopyOnWriteArrayList 반복 할 수 있도록 할

당신이 참조를 저장했다를 제외하고는 연결이 끊긴 사람을 제거 할 필요가 없습니다 것입니다

물론 그들에게. 그렇지 않으면이 요구 사항에 대해 정말로 언급 할 수 없습니다.

1

연결 당 스레드 수를 선택하고 NIO API를 사용하지 않으려면이 방법이 좋은 해결책이라고 생각합니다. 그러나 풀 크기가 동시 요청 수보다 작 으면 이전 요청이 끝날 때까지 대기중인 클라이언트가있는 것을 기억하십시오.

작업에서 예외가 발생하면 어떻게됩니까? 스레드가 종료되지만 실행자가 다른 스레드를 생성합니다.

관련 문제