Java: Является ли ServerSocket.accept потокобезопасным?

Для проекта в школе мы создаем многопоточный сервер в Java 5.0. Этот проект сосредоточен на аспекте совпадения сервера.

У нас есть потоки, посвященные обработке запросов. Для этого у них есть вызов ServerSocket.accept() для приема новых соединений. Наш выбор состоял в том, чтобы начать их кучу и позволить им обрабатывать входящие соединения с предположением, что два потока не могут принимать() одно и то же соединение одновременно.

Но теперь основная проблема заключается в том, что мы не можем найти что-либо в API, который гарантирует нам это поведение (или мы не выглядели правильно), и у нас нет ничего, кроме доказательства "он работает".

Есть ли у кого-нибудь источник поиска такого рода информации о java-методах?

Ответ 1

Короткий ответ: если в документации не указано, что что-то является потокобезопасным, тогда вы должны предположить, что это не так. Вам необходимо выполнить координацию между потоками, чтобы убедиться, что ни один из двух потоков не использует серверный сокет в одно и то же время.

Это особенно важно, потому что какой-то другой код мог зарегистрировать свою собственную реализацию сокета с ServerSocket.setSocketFactory. Даже если реализация сокета по умолчанию является потокобезопасной, пользовательские реализации не обязательно должны быть. В документации нет ничего.

Длинный ответ: Реализация Windows по умолчанию

Вы можете загрузить и проверить java SE 1.6 исходный код.

Я начал с \j2se\src\share\classes\java\net\ServerSocket.java, и оттуда след привел к PlainSocketImpl.java. Метод PlainSocketImpl.Accept помечен как native.

Собственный код С++ для окон находится в \j2se\src\windows\native\java\net\PlainSocketImpl.c. Он использует функцию winsock accept. Из статьи

Ответ 2

Это не совсем ответит на ваш вопрос, но запуск 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();
}