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