Java: действительно ли ServerSocket.accept ориентирован на многопотоковое исполнение?

По моему мнению, надругаться над сервером REST - лучший, более чистый вариант. Попробуйте Mountebank ( http://www.mbtest.org ). Удивительный инструмент службы виртуализации.

12
задан Piotr Dobrogost 6 July 2009 в 16:07
поделиться

2 ответа

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

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

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

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

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

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

В Windows NT и Windows 2000, Поддержка сокетов Windows для 16-битных приложение основано на WINSOCK.DLL. Для 32-битных приложений поддержка находится в WSOCK32.DLL. Предоставляемые API идентичны, за исключением того, что 32-битные версии имеют параметры расширены до 32 биты. В Win32 безопасность потоков

Так что, по крайней мере, в Windows, Socket.Accept является потокобезопасным в том смысле, что он не позволяет двум потокам принимать одно и то же соединение. В реализации ServerSocket также есть инфраструктура (например, метод Close () использует блокировку), которая указывает на то, что он предназначен для обеспечения потоковой безопасности.

26
ответ дан 2 December 2019 в 04:17
поделиться

Это не совсем ответ на ваш вопрос, но запуск 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();
}
9
ответ дан 2 December 2019 в 04:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: