2009-05-22 12 views
11

Okuldaki bir proje için, Java 5.0'da çok iş parçacıklı bir sunucu oluşturuyoruz. Bu proje bir sunucunun ortak yönüne odaklanmıştır.Java: ServerSocket.iscept threadsafe nedir?

İsteklerin işlenmesi için ayrılmış bazı iş parçacıklarımız var. Bunu yapmak için, yeni bağlantıları kabul etmek için ServerSocket.accept() öğesine bir çağrıları vardır. Bizim seçimimiz bir demet başlatmak ve aynı anda iki parçanın aynı bağlantıyı kabul edemeyeceği varsayımıyla gelen bağlantıları ele almaktı.

Ama şimdi asıl sorun o garanti bize bu davranışı API şey bulamıyorum ki (ya biz doğru bakmadı) ve biz "çalıştığını" kanıt dışında hiçbir şey yok.

Birisi, java yöntemleriyle ilgili bu tür bilgileri aramak için bir kaynağa sahip midir? Sunucunun tasarımı ile sorun var gibi birden çok iş parçacığı üzerinde

+0

Bu tasarımın gerçekten iyi olmadığını biliyoruz ve zaten bir çalışan iş parçacığı havuzu kullanmayı değiştirdik. Şimdi, çalışan iş parçacıklarına istekleri kabul eden ve gönderen yalnızca bir iş parçacığımız var. Hala java yöntemlerinin iş parçacığı güvenliği hakkında bir bilgi olup olmadığını biliyorum. –

cevap

25

Kısa cevap:

Kodunuz gerektiği şöyle görünür dokümantasyon o zaman değil mi olduğunu düşünür, bir şey parçacığı güvenli olduğunu belirtmek etmezse. İki iş parçacığının aynı anda sunucu soketini kullanmadığından emin olmak için iş parçacıkları arasındaki koordinasyonu kendiniz yapmanız gerekir. diğer bazı kod ServerSocket.setSocketFactory ile kendi soket uygulaması kayıtlı olabilirdi çünkü

bu özellikle önemlidir. Varsayılan soket uygulaması iş parçacığı güvenli olsa bile, özel uygulamaların olması gerekmez. Belgede böyle bir şey yok.

Uzun cevap: indirebilir ve java SE 1.6 source code inceleyebilir Standart, Windows Uygulama

.

Ben \j2se\src\share\classes\java\net\ServerSocket.java başladı ve oradan iz PlainSocketImpl.java yol açtı. PlainSocketImpl.Accept yöntemi, native olarak işaretlenmiştir. Pencereler için

doğal C++ kod \j2se\src\windows\native\java\net\PlainSocketImpl.c bulunmaktadır. winsock accept işlevini kullanır. Bir MSDN article on WinSock (vurgu mayın) Gönderen:

Windows NT ve Windows 2000 altında

, 16 bit uygulamalar için , Windows Sockets desteği WINSOCK.DLL dayanmaktadır. 32 bit uygulamalar için destek WSOCK32.DLL dosyasındadır. sağlanan API'ler, 32 bit sürümlerinin 32 bit'e genişletilmiş parametreler dışında aynıdır. Win32 altında, dişli güvenliği temin edilen .

Yani en azından pencerelerde, Socket.Accept iki iş parçacığı aynı bağlantıyı kabul izin vermez anlamda iş parçacığı güvenli. Ayrıca, ServerSocket uygulamasında altyapı var (e.g. Close() yöntemi, iş parçacığı güvenli olması amaçlandığını belirten bir kilit kullanır.

+2

+1 + – talonx

+0

tekrar +1 – Kartoch

8

Bu oldukça sorunuza cevap vermez, ama kabul çalışıyor() duyulur.

Genellikle, birden çok iş parçacığından accept() komutunu çalıştırmaya gerek yoktur.

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

Kendi bağlantısını kabul eden her bir iş parçacığı mükemmel bir tasarımdır. Diğer iş parçacıklarına teslim olmamaktan yararlanır. –

+1

Her iş parçacığının kabul() için yarıştığı sabit bir iş parçacığı mı düşünüyorsunuz? Bu, her zamanki iş parçacığının bir işleyişidir. Yeni bir iş parçacığına (veya bir iş parçacığından) "teslim etme maliyetinin" çoğu durumda karmaşıklığı nasıl haklı çıkaracağını göremediğimi itiraf etmeliyim. Bu tür tasarımın pratik olduğu herhangi bir örnek var mı? – Nuoji

+3

Daha da önemlisi, Java kabul etmez * iş parçacığı güvenliğini garanti etmez * - Altta yatan yerel API'nin Windows'da yaptığı gerçeği (kabul edilen cevap ile belirtildiği gibi) anlamsızdır. Bu büyük cevap için ayrıntılı, iyi araştırılmış cevap için –

İlgili konular