2009-05-22 37 views
11

Đối với một dự án ở trường, chúng tôi đang tạo một máy chủ đa luồng trong Java 5.0. Dự án này tập trung vào khía cạnh đồng nhất của một máy chủ.Java: Là ServerSocket.accept threadsafe?

Chúng tôi có một số chủ đề chuyên xử lý các yêu cầu. Để làm như vậy, họ có một cuộc gọi đến một ServerSocket.accept() để chấp nhận các kết nối mới. Sự lựa chọn của chúng tôi là bắt đầu một loạt chúng và để chúng xử lý các kết nối đến với giả thiết rằng hai luồng không thể chấp nhận() cùng một kết nối cùng một lúc. Nhưng bây giờ vấn đề chính là chúng tôi không thể tìm thấy bất cứ điều gì trong API bảo đảm cho chúng tôi hành vi này (hoặc chúng tôi không nhìn đúng) và chúng tôi không có gì ngoại trừ bằng chứng "nó hoạt động".

Có ai đó là nguồn để tìm loại thông tin này trên các phương thức java không?

+0

Chúng tôi biết rằng thiết kế này không thực sự tốt và chúng tôi đã thay đổi nó để sử dụng một nhóm các chuỗi công nhân. Bây giờ chúng ta chỉ có một luồng chấp nhận và gửi các yêu cầu tới các luồng công nhân. Tôi vẫn sẽ biết liệu có thông tin nào đó về chủ đề an toàn của các phương pháp java hay không. –

Trả lời

25

Câu trả lời ngắn: nếu tài liệu không xác định rằng cái gì là chủ đề an toàn, sau đó bạn phải thừa nhận rằng nó không phải là. Bạn cần phải phối hợp giữa các luồng để đảm bảo rằng không có hai luồng nào sử dụng socket máy chủ cùng một lúc.

Điều này đặc biệt quan trọng vì một số mã khác có thể đã đăng ký triển khai socket riêng của mình với ServerSocket.setSocketFactory. Ngay cả khi việc triển khai socket mặc định là an toàn luồng, việc triển khai tùy chỉnh không nhất thiết phải như vậy. Không có gì trong tài liệu nói như vậy.

Long trả lời: mặc định của Windows Thực hiện

Bạn có thể tải về và kiểm tra việc java SE 1.6 source code.

Tôi bắt đầu tại \j2se\src\share\classes\java\net\ServerSocket.java và từ đó đường nhỏ dẫn đến PlainSocketImpl.java. Phương pháp PlainSocketImpl.Accept được đánh dấu là native.

Mã C++ gốc cho cửa sổ nằm trong \j2se\src\windows\native\java\net\PlainSocketImpl.c. Nó sử dụng hàm winsock accept. Từ một (tôi nhấn mạnh) MSDN article on WinSock:

Dưới Windows NT và Windows 2000, Windows Sockets hỗ trợ cho ứng dụng 16-bit được dựa trên WINSOCK.DLL. Đối với các ứng dụng 32 bit, hỗ trợ nằm trong WSOCK32.DLL. Các API được cung cấp giống hệt nhau ngoại trừ các phiên bản 32 bit có tham số được mở rộng đến 32 bit. Theo Win32, an toàn chủ đề là được cung cấp.

Vì vậy, ít nhất là trên cửa sổ, Socket.Accept là chủ đề an toàn theo nghĩa là nó sẽ không cho phép hai luồng chấp nhận cùng một kết nối. Cũng có cơ sở hạ tầng trong việc thực hiện ServerSocket (e.g. phương thức Close() sử dụng khóa) cho biết rằng nó được dự định là luồng an toàn.

+2

+1 cho câu trả lời chi tiết, được nghiên cứu tốt – talonx

+0

một lần nữa +1 cho câu trả lời tuyệt vời này – Kartoch

8

Điều này không hoàn toàn trả lời câu hỏi của bạn, nhưng chạy accept() trên nhiều luồng có vẻ như có sự cố với thiết kế của máy chủ.

Thông thường không cần phải chạy accept() từ nhiều chuỗi.

Mã của bạn nên trông giống như sau:

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

Mỗi chuỗi công nhân chấp nhận kết nối riêng của nó là một thiết kế hoàn toàn hợp lệ. Nó được hưởng lợi từ việc không phải bàn giao cho các chủ đề khác. –

+1

Bạn đang nghĩ đến một threadpool cố định trong đó mỗi thread cạnh tranh cho accept()? Đó chắc chắn là một nghịch đảo của quyền sở hữu chủ đề thông thường. Tôi phải thừa nhận rằng tôi không thể thấy làm thế nào "chi phí bàn giao" cho một chủ đề mới (hoặc một từ một threadpool) sẽ biện minh cho sự phức tạp trong nhiều trường hợp. Có bất kỳ ví dụ nào về kiểu thiết kế này thực tế không? – Nuoji

+3

Quan trọng hơn, Java không * KHÔNG * đảm bảo an toàn luồng của chấp nhận - Thực tế là API gốc cơ bản làm trong Windows (như được trích dẫn bởi câu trả lời được chấp nhận), là vô nghĩa. –

Các vấn đề liên quan