2009-05-22 3 views
11

학교 프로젝트의 경우 Java 5.0에서 멀티 스레드 서버를 만들고 있습니다. 이 프로젝트는 서버의 동시성 측면을 중심으로합니다.Java : ServerSocket.accept는 threadsafe입니까?

우리는 요청 처리 전용 스레드가 있습니다. 그렇게하기 위해서 (때문에)는, 새로운 접속을 받아들이는 ServerSocket.accept()를 호출합니다. 우리의 선택은 많은 것을 시작하여 두 개의 스레드가 동시에 같은 연결을 받아 들일 수 없다는 가정하에 들어오는 연결을 처리하게하는 것이 었습니다.

그러나 이제 큰 문제는 우리가 보증 우리에게이 동작을 API에서 아무것도 찾을 수 없습니다 (또는 우리가 잘 보이지 않았다) 우리는 "작동"증거를 제외하고 아무것도 없다.

사람에게 자바 방법에 대한 이런 종류의 정보를 찾을 수있는 소스를 가지고? 서버의 설계에 문제가있는 것처럼 여러 스레드에

+0

이 디자인은별로 좋지 않으며 이미 작업자 스레드 풀을 사용하도록 변경했습니다. 이제는 요청을 수락하고 작업자 스레드로 보내는 단 하나의 스레드 만 있습니다. Java 메소드의 스레드 안전성에 대한 정보가 있다면 알 수 있습니다. –

답변

25

짧은 답변 :

코드는해야 이런 식으로 뭔가를 보이는 문서가 당신이 그렇지 않은 가정해야한다, 무언가가 스레드 안전하다는 것을 지정하지 않는 경우. 두 스레드가 동시에 서버 소켓을 사용하지 않도록 스레드간에 조정해야합니다. 다른 코드 ServerSocket.setSocketFactory와 함께 자신의 소켓 구현을 등록 할 수 있기 때문에

이 특히 중요합니다. 기본 소켓 구현이 스레드로부터 안전하더라도 사용자 정의 구현은 필요하지 않습니다. 문서에 아무것도 언급되어 있지 않습니다.

긴 대답 : 당신은 다운로드하고 java SE 1.6 source code를 검사 할 수있는 기본 Windows 구현

.

내가 \j2se\src\share\classes\java\net\ServerSocket.java에서 시작하여 거기에서 흔적이 PlainSocketImpl.java으로 이어진다. PlainSocketImpl.Accept 메서드는 native으로 표시됩니다.

Windows 용 기본 C++ 코드는 \j2se\src\windows\native\java\net\PlainSocketImpl.c입니다. 그것은 winsock accept 기능을 사용합니다. MSDN article on WinSock (강조 광산)에서 :

Windows NT 및 Windows 2000에서

, 16 비트 응용 프로그램에 대한 Windows 소켓 지원은 WINSOCK.DLL을 기반으로합니다. 32 비트 응용 프로그램의 경우 은 WSOCK32.DLL에 있습니다. 제공된 의 API는 32 비트 버전의 매개 변수가 32 비트로 넓어지는 것을 제외하고는 동일합니다. Win32에서 스레드 안전성은 입니다.

그래서 적어도 창에, Socket.Accept는 두 개의 스레드가 같은 연결을 허용 못하게한다는 점에서 스레드로부터 안전합니다. 또한 구현 (예를 들어,지. Close() 메서드는 스레드 안전성을 나타내는 잠금을 사용합니다.

+2

자세한 내용은 잘 조사 된 답변 – talonx

+0

+1이 훌륭한 대답은 +1입니다. – Kartoch

8

이 매우 귀하의 질문에 대답하지 않지만, 받아 실행은() 소리가 난다.

는 일반적으로 여러 스레드에서 accept()를 실행할 필요가 없습니다.

while (serverIsUpAndRunning()) 
{ 
    // Wait for an incoming connection. 
    Socket s = serverSocket.accept(); 
    // Spawn a thread to handle the socket, 
    // so that we don't block new connections. 
    SocketHandlerThread t = new SocketHandlerThread(s); 
    t.start(); 
} 
+0

자체 연결을 허용하는 각 작업자 스레드는 완벽하게 유효한 디자인입니다. 다른 스레드로 전달하지 않아도되는 이점이 있습니다. –

+1

각 스레드가 accept()를 위해 경쟁하는 고정 된 스레드 풀을 생각하고 계십니까? 그것은 틀림없이 일반적인 스레드 소유권을 뒤집습니다. 나는 대부분의 경우에 새로운 쓰레드 (또는 쓰래드 풀에서 하나의 쓰레드 풀까지)가 어떻게 "복잡성을 정당화하는지"알 수 없다는 것을 인정해야한다. 이런 종류의 디자인이 실용적인 예가 있습니까? – Nuoji

+3

더 중요한 것은, Java는 accept의 스레드 안전성을 보장하지 않는다는 것입니다. - 기본 네이티브 API가 Windows에서 수행한다는 사실 (수용된 응답에서 인용)은 의미가 없습니다. –

관련 문제