简体   繁体   English

Java:ServerSocket.accept线程安全吗?

[英]Java : Is ServerSocket.accept threadsafe?

For a project in school, we are making a multithreaded server in Java 5.0. 对于学校的项目,我们在Java 5.0中创建一个多线程服务器。 This project is centered on the concurrence aspect of a server. 该项目以服务器的并发方面为中心。

We have some threads dedicated to treating the requests. 我们有一些致力于处理请求的线程。 To do so, they have a call to a ServerSocket.accept() to accept new connections. 为此,他们调用ServerSocket.accept()来接受新连接。 Our choice was to start a bunch of them and let them treat the incoming connections with the assumption that two threads cannot accept() the same connection at the same time. 我们的选择是启动一堆它们并让它们处理传入的连接,假设两个线程不能同时接受()相同的连接。

But now the main problem is that we cannot find anything in the API that guaranty us this behavior (or we didn't look right) and we have nothing except the "it works" proof. 但现在主要的问题是我们在API中找不到保证我们这种行为的任何东西(或者我们看起来不对),除了“它的工作”证明之外什么都没有。

Has someone a source to look for this sort of information on the java methods ? 有人来源寻找有关java方法的这类信息吗?

Short answer : if the documentation does not specify that something is thread safe, then you must assume that it is not. 简短回答 :如果文档没有指定某些东西是线程安全的,那么你必须假设它不是。 You need to do the coordination between threads yourself to make sure that no two threads use the server socket at the same time. 您需要自己在线程之间进行协调,以确保没有两个线程同时使用服务器套接字。

This is especially important because some other code could have registered its own socket implementation with ServerSocket.setSocketFactory . 这一点尤为重要,因为其他一些代码可能已经使用ServerSocket.setSocketFactory注册了自己的套接字实现。 Even if the default socket implementation is thread-safe, custom implementations don't have to be. 即使默认套接字实现是线程安全的,也不一定是自定义实现。 There is nothing in the documentation that says so. 文档中没有任何内容可以解释。

Long answer: the Default Windows Implementation 答案很长:默认的Windows实现

You can download and inspect the java SE 1.6 source code . 您可以下载并检查java SE 1.6源代码

I started at \\j2se\\src\\share\\classes\\java\\net\\ServerSocket.java and from there the trail led to PlainSocketImpl.java . 我从\\j2se\\src\\share\\classes\\java\\net\\ServerSocket.java ,从那里开始导致PlainSocketImpl.java The PlainSocketImpl.Accept method is marked as native . PlainSocketImpl.Accept方法标记为本native

The native C++ code for windows is in \\j2se\\src\\windows\\native\\java\\net\\PlainSocketImpl.c . Windows的本机C ++代码位于\\j2se\\src\\windows\\native\\java\\net\\PlainSocketImpl.c It uses the winsock accept function. 它使用winsock接受函数。 From an MSDN article on WinSock (emphasis mine): 关于WinSockMSDN文章 (强调我的):

Under Windows NT and Windows 2000, Windows Sockets support for 16-bit applications is based on WINSOCK.DLL. 在Windows NT和Windows 2000下,对16位应用程序的Windows套接字支持基于WINSOCK.DLL。 For 32-bit applications, the support is in WSOCK32.DLL. 对于32位应用程序,支持在WSOCK32.DLL中。 The APIs provided are identical except that the 32-bit versions have parameters widened to 32 bits. 提供的API是相同的,只是32位版本的参数扩展到32位。 Under Win32, thread safety is supplied. 在Win32下,提供了线程安全性。

So at least on windows, Socket.Accept is thread safe in the sense that it will not let two threads accept the same connection. 所以至少在Windows上, Socket.Accept是线程安全的,因为它不会让两个线程接受相同的连接。 There also is infrastructure in the ServerSocket implementation (eg the Close() method uses a lock) which indicates that it is intended to be thread safe. ServerSocket实现中还有基础结构(例如,Close()方法使用锁),表明它是线程安全的。

This does not quite answer your question, but running accept() on multiple threads sounds like there is something wrong with the design of the server. 这并没有完全回答你的问题,但在多个线程上运行accept()听起来像服务器的设计有问题。

Usually there should be no need to run accept() from multiple threads. 通常不需要从多个线程运行accept()。

Your code should looks something like this: 您的代码应如下所示:

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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM