Java:ServerSocket.accept线程安全吗?

Tho*_*ery 12 java multithreading thread-safety

对于学校的项目,我们在Java 5.0中创建一个多线程服务器.该项目以服务器的并发方面为中心.

我们有一些致力于处理请求的线程.为此,他们调用ServerSocket.accept()来接受新连接.我们的选择是启动一堆它们并让它们处理传入的连接,假设两个线程不能同时接受()相同的连接.

但现在主要的问题是我们在API中找不到保证我们这种行为的任何东西(或者我们看起来不对),除了"它的工作"证明之外什么都没有.

有人来源寻找有关java方法的这类信息吗?

Wim*_*nen 26

简短回答:如果文档没有指定某些东西是线程安全的,那么你必须假设它不是.您需要自己在线程之间进行协调,以确保没有两个线程同时使用服务器套接字.

这一点尤为重要,因为其他一些代码可能已经注册了自己的套接字实现ServerSocket.setSocketFactory.即使默认套接字实现是线程安全的,也不一定是自定义实现.文档中没有任何内容可以解释.

答案很长:默认的Windows实现

您可以下载并检查java SE 1.6源代码.

\j2se\src\share\classes\java\net\ServerSocket.java从那里开始,然后从那里开始PlainSocketImpl.java.该PlainSocketImpl.Accept方法标记为native.

Windows的本机C++代码在\j2se\src\windows\native\java\net\PlainSocketImpl.c.它使用winsock接受函数.从关于WinSockMSDN文章(强调我的):

在Windows NT和Windows 2000下,对16位应用程序的Windows套接字支持基于WINSOCK.DLL.对于32位应用程序,支持在WSOCK32.DLL中.提供的API是相同的,只是32位版本的参数扩展到32位.在Win32下,提供了线程安全性.

所以至少在Windows上,Socket.Accept线程是安全的,因为它不会让两个线程接受相同的连接.实现中还有基础结构ServerSocket(例如,Close()方法使用锁),表明它是线程安全的.

  • +1详细,研究得很好的答案 (2认同)

Nuo*_*oji 9

这并没有完全回答你的问题,但在多个线程上运行accept()听起来像服务器的设计有问题.

通常不需要从多个线程运行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();
}
Run Code Online (Sandbox Code Playgroud)

  • 更重要的是,Java确实*不*保证接受的线程安全性 - 底层本机API在Windows中的作用(由接受的答案引用)是没有意义的. (3认同)