views:

1017

answers:

2

For a project in school, we are making a multithreaded server in 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. 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.

Has someone a source to look for this sort of information on the java methods ?

+3  A: 

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.

Usually there should be no need to run accept() from multiple threads.

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();
}
Nuoji
Each worker thread accepting its own connection is a perfectly valid design. It benefits from not having to hand off to other threads.
Tom Hawtin - tackline
You're thinking of a fixed threadpool where each thread compete for the accept()? That's certainly an inversal of the usual thread ownership. I must admit that I can't see how "the cost of handing over" to a new thread (or one from a threadpool) would justify the complexity in most cases. Are there any examples where this sort of design is practical?
Nuoji
More importantly, Java does *NOT* guarantee the thread safety of accept - The fact that the underlying native API does in Windows (as cited by the accepted answer), is meaningless.
Software Monkey
+10  A: 

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. 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

You can download and inspect the java SE 1.6 source code.

I started at \j2se\src\share\classes\java\net\ServerSocket.java and from there the trail led to PlainSocketImpl.java. The PlainSocketImpl.Accept method is marked as native.

The native C++ code for windows is in \j2se\src\windows\native\java\net\PlainSocketImpl.c. It uses the winsock accept function. From an MSDN article on WinSock (emphasis mine):

Under Windows NT and Windows 2000, Windows Sockets support for 16-bit applications is based on WINSOCK.DLL. For 32-bit applications, the support is in WSOCK32.DLL. The APIs provided are identical except that the 32-bit versions have parameters widened to 32 bits. Under Win32, thread safety is supplied.

So at least on windows, Socket.Accept is thread safe in the sense that it will not let two threads accept the same connection. There also is infrastructure in the ServerSocket implementation (e.g. the Close() method uses a lock) which indicates that it is intended to be thread safe.

Wim Coenen
+1 for the detailed, well researched answer
talonx