Прерываемый сетевой ввод / вывод в Java
1108 просмотра
2 ответа
В Java 1.4+ есть 3 способа прервать поток, который блокируется на сокете ввода-вывода:
- Если сокет был создан с использованием обычного
java.net.Socket(InetAddress, int)
конструктора, я могу закрыть его из отдельного потока. В результатеSocketException
в заблокированную нить вбрасывается. - Если сокет был создан с помощью
SocketChannel.open(...)
.socket()
(неблокирующий ввод / вывод) - снова можно закрыть его из отдельного потока, но теперьAsynchronousCloseException
в заблокированном потоке возникает другое исключение (an ). - Кроме того, в случае использования неблокирующего ввода / вывода можно прервать заблокированный поток с помощью
ClosedByInterruptException
выброса. Прерывание заблокированного потока при использовании ввода-вывода Java старого стиля не влияет на поток.
Вопросов:
- Является ли закрытие сокета из отдельного потока потокобезопасным при использовании ввода-вывода старого стиля? Если нет, каковы альтернативы?
- Является ли закрытие сокета / канала из отдельного потока потокобезопасным при использовании вместо этого NIO?
- Есть ли разница в
Socket.close()
поведении при использовании NIO в отличие от обычного ввода-вывода? - Есть ли какие-либо преимущества использования NIO для работы в сети, кроме возможности завершить заблокированную операцию ввода-вывода простым прерыванием потока (чтобы мне больше не нужно было хранить ссылку на сокет)?
Ответы (2)
3 плюса
Является ли закрытие сокета из отдельного потока потокобезопасным при использовании ввода-вывода старого стиля? Если нет, каковы альтернативы?
да.
Альтернативой является использование блокирования NIO (что является поведением по умолчанию для SocketChannel BTW). Я предпочитаю это для небольшого числа соединений, поскольку оно имеет эффективность NIO, но некоторые из простоты простого ввода-вывода.
Является ли закрытие сокета / канала из отдельного потока потокобезопасным при использовании вместо этого NIO?
И для блокирования NIO, и без блокировки NIO, они являются поточно-ориентированными.
Есть ли разница в поведении Socket.close () при использовании NIO в отличие от обычного ввода-вывода?
Если вам нужно узнать подробности, я предлагаю вам прочитать код, но в основном они одинаковы.
Есть ли какие-либо преимущества использования NIO для работы в сети, кроме возможности завершить заблокированную операцию ввода-вывода простым прерыванием потока (чтобы мне больше не нужно было хранить ссылку на сокет)?
То, как вы закрываете соединение, вызывает наименьшее беспокойство. Так что да, есть много причин, чтобы рассмотреть NIO поверх простого ввода-вывода.
Плюсы для NIO
- Быстрее и легче при использовании прямой памяти
- Более масштабируемый для десятков тысяч пользователей.
- Поддерживает эффективное занятое ожидание.
Cons
- Простой IO проще для кодирования.
- По этой причине многие API поддерживают только простой ввод-вывод.
0 плюса
1) Так как ошибка вызова основной ОС, которая вызывает исключение, происходит из стека TCP, который поддерживает многопоточность, не должно быть никаких проблем.
2) Не уверен - не пробовал, но был бы удивлен, если бы была какая-либо проблема.
3) Могут быть некоторые различия в производительности. Вызов OS close () требует четырехстороннего рукопожатия с одноранговым TCP-сервером - не уверен, какая ОС поддерживает эту функцию неблокирующим образом (то же самое с connect).
4) Резьба .. или розетка. Вы должны сохранить ссылку на что-то. Поскольку вы закрываете сокет, кажется разумным сохранить ссылку на него :)
Автор: Martin James Размещён: 15.10.2013 12:09Вопросы из категории :
- java В чем разница между int и Integer в Java и C #?
- java Как я могу определить IP моего маршрутизатора / шлюза в Java?
- java Каков наилучший способ проверки XML-файла по сравнению с XSD-файлом?
- java Как округлить результат целочисленного деления?
- java Преобразование списка <Integer> в список <String>
- multithreading Что такое состояние гонки?
- multithreading Что такое тупик?
- multithreading Что такое мьютекс?
- multithreading Как начать потоки в plain C?
- multithreading Потокобезопасный foreach перечисление списков
- io Почему в Ruby нет реального StringBuffer или StringIO?
- io How to find out if a file exists in C# / .NET?
- io Легкий способ записи содержимого Java InputStream в OutputStream
- io Отправка того же, но модифицированного объекта через ObjectOutputStream
- io Получить OutputStream в строку
- nio когда я использую nio, serverSocket.accept () выбрасывает IllegalBlockingModeException
- nio Получает байтовый массив из ByteBuffer в Java
- nio Java NIO: Что такое IOException: Сломанная труба означает?
- nio Java: преобразование строки в и из ByteBuffer и связанных с ней проблем
- nio Рекурсивно перечислять файлы в Java