2012-05-07 39 views
5

Tôi biết rằng an toàn luồng của ổ cắm java đã được thảo luận trong một số chủ đề ở đây trên stackoverflow, nhưng tôi đã không thể tìm thấy câu trả lời rõ ràng cho câu hỏi này - Có, trong thực tế, an toàn để có nhiều chủ đề đồng thời ghi vào cùng SocketOutputStream, hoặc có nguy cơ dữ liệu được gửi từ một luồng được trộn lẫn với dữ liệu từ một bước khác không? (Ví dụ, người nhận ở đầu kia đầu tiên nhận được nửa đầu của thông điệp của một sợi và sau đó một số dữ liệu từ thông điệp của một sợi khác và sau đó là phần còn lại của thông điệp của chủ đề đầu tiên)An toàn chủ đề của SocketOutputStream

Lý do tôi nói "trên thực tế" là Tôi biết các lớp Socket không được ghi nhận là an toàn thread, nhưng nếu nó thực sự là an toàn trong hiện tại, thì đó là đủ tốt cho tôi. Việc triển khai cụ thể mà tôi tò mò nhất là Hotspot chạy trên Linux.

Khi xem xét lớp Java của triển khai điểm phát sóng, cụ thể hơn là việc thực hiện socketWrite() trong SocketOutputStream, có vẻ như nó phải là luồng an toàn miễn là việc triển khai thực hiện socketWrite0() là an toàn. Tuy nhiên, khi xem xét việc triển khai phương thức đó (j2se/src/solaris/native/java/net/SocketOutputStream.c), có vẻ như chia dữ liệu được gửi thành các khối 64 hoặc 128kb (tùy thuộc vào việc đó là một 64bit hay không) JVM) và sau đó gửi các khối trong riêng biệt viết. Vì vậy, với tôi, có vẻ như gửi hơn 64kb từ các chủ đề khác nhau không an toàn, nhưng nếu nó nhỏ hơn 64kb thì nó sẽ an toàn ... nhưng tôi có thể rất thiếu một thứ gì đó quan trọng ở đây. Có ai khác ở đây xem xét điều này và đi đến kết luận khác không?

Trả lời

5

Tôi nghĩ rằng đó thực sự là ý tưởng tồi của một điều gì đó có thể thay đổi ngoài tầm kiểm soát của bạn. Nếu bạn làm một cái gì đó như thế này, bạn sẽ phải kiểm soát rất cẩn thận các phiên bản của mọi thứ bạn sử dụng để đảm bảo rằng đó là những gì bạn mong đợi và điều đó rất khó thực hiện. Và bạn cũng sẽ phải có một bộ thử nghiệm rất mạnh mẽ để xác minh rằng các hàm operat đa luồng chính xác vì bạn phụ thuộc vào việc kiểm tra mã và các tin đồn từ các randoms trên StackOverflow cho giải pháp của bạn.

Tại sao bạn không thể đưa SocketOutputStream vào một OutputStream khác và sau đó thêm đồng bộ hóa cần thiết ở cấp đó? Nó an toàn hơn nhiều để làm điều đó theo cách đó và bạn ít có khả năng có vấn đề bất ngờ xuống đường.

+1

Đồng ý .. bạn có thể có một mô hình sản xuất/tiêu dùng với một BlockingDeque rằng các nhà sản xuất (viết) gắn liền với các và người tiêu dùng (người gửi) kéo vật tắt phía trước để gửi. – sjr

+0

Cảm ơn bạn đã dành thời gian trả lời. Cho dù đó là một ý tưởng hay không có thể gây tranh cãi.Cá nhân tôi không nghĩ rằng đó là _necessarily_ một ý tưởng tồi để làm những điều phụ thuộc vào việc thực hiện cụ thể. Có rất nhiều lý do khác tại sao người ta có thể muốn sử dụng java bên cạnh ý tưởng "viết một lần chạy bất cứ nơi nào". Nếu hiệu suất là rất quan trọng, việc có thể chạy mã của bạn trên bất kỳ triển khai nào có thể là một yêu cầu bạn sẵn sàng bỏ. – oscar11

+0

Tôi biết rằng hoặc thêm khóa xung quanh viết hoặc đảm bảo rằng chỉ có một nhà văn duy nhất bằng cách sử dụng một luồng riêng biệt và hàng đợi chặn sẽ "giải quyết" vấn đề. Tuy nhiên, việc sử dụng hàng đợi chặn sẽ gây ra quá nhiều thời gian chờ cho yêu cầu của tôi và đồng bộ hóa quyền truy cập để viết thực sự an toàn, sẽ rất tuyệt nếu bạn không thực sự cần thiết. – oscar11

2

Theo tài liệu này http://www.docjar.com/docs/api/java/net/SocketOutputStream.html, lớp học không yêu cầu là chuỗi an toàn, và do đó giả sử không phải là chủ đề. Nó kế thừa từ FileOutputStream, mà thường tập tin I/O không phải là chủ đề an toàn.

Lời khuyên của tôi là nếu lớp học liên quan đến phần cứng hoặc truyền thông, nó không phải là luồng an toàn hoặc "chặn". Lý do là hoạt động an toàn thread tiêu tốn nhiều thời gian hơn, điều mà bạn có thể không thích. Nền của tôi không có trong Java nhưng các thư viện khác tương tự về triết học.

Tôi nhận thấy bạn đã kiểm tra lớp học rộng rãi, nhưng bạn có thể kiểm tra cả ngày trong nhiều ngày và có thể không chứng minh được điều gì, 2 xu của tôi.

Chúc may mắn & vui chơi với nó.

Tommy Kwee