Прерываемый сетевой ввод / вывод в Java

java multithreading io nio

1108 просмотра

2 ответа

1961 Репутация автора

В Java 1.4+ есть 3 способа прервать поток, который блокируется на сокете ввода-вывода:

  1. Если сокет был создан с использованием обычного java.net.Socket(InetAddress, int)конструктора, я могу закрыть его из отдельного потока. В результате SocketExceptionв заблокированную нить вбрасывается.
  2. Если сокет был создан с помощью SocketChannel.open(...). socket()(неблокирующий ввод / вывод) - снова можно закрыть его из отдельного потока, но теперь AsynchronousCloseExceptionв заблокированном потоке возникает другое исключение (an ).
  3. Кроме того, в случае использования неблокирующего ввода / вывода можно прервать заблокированный поток с помощью ClosedByInterruptExceptionвыброса. Прерывание заблокированного потока при использовании ввода-вывода Java старого стиля не влияет на поток.

Вопросов:

  1. Является ли закрытие сокета из отдельного потока потокобезопасным при использовании ввода-вывода старого стиля? Если нет, каковы альтернативы?
  2. Является ли закрытие сокета / канала из отдельного потока потокобезопасным при использовании вместо этого NIO?
  3. Есть ли разница в Socket.close()поведении при использовании NIO в отличие от обычного ввода-вывода?
  4. Есть ли какие-либо преимущества использования NIO для работы в сети, кроме возможности завершить заблокированную операцию ввода-вывода простым прерыванием потока (чтобы мне больше не нужно было хранить ссылку на сокет)?
Автор: Bass Источник Размещён: 15.10.2013 11:54

Ответы (2)


3 плюса

463335 Репутация автора

Решение

Является ли закрытие сокета из отдельного потока потокобезопасным при использовании ввода-вывода старого стиля? Если нет, каковы альтернативы?

да.

Альтернативой является использование блокирования NIO (что является поведением по умолчанию для SocketChannel BTW). Я предпочитаю это для небольшого числа соединений, поскольку оно имеет эффективность NIO, но некоторые из простоты простого ввода-вывода.

Является ли закрытие сокета / канала из отдельного потока потокобезопасным при использовании вместо этого NIO?

И для блокирования NIO, и без блокировки NIO, они являются поточно-ориентированными.

Есть ли разница в поведении Socket.close () при использовании NIO в отличие от обычного ввода-вывода?

Если вам нужно узнать подробности, я предлагаю вам прочитать код, но в основном они одинаковы.

Есть ли какие-либо преимущества использования NIO для работы в сети, кроме возможности завершить заблокированную операцию ввода-вывода простым прерыванием потока (чтобы мне больше не нужно было хранить ссылку на сокет)?

То, как вы закрываете соединение, вызывает наименьшее беспокойство. Так что да, есть много причин, чтобы рассмотреть NIO поверх простого ввода-вывода.

Плюсы для NIO

  • Быстрее и легче при использовании прямой памяти
  • Более масштабируемый для десятков тысяч пользователей.
  • Поддерживает эффективное занятое ожидание.

Cons

  • Простой IO проще для кодирования.
  • По этой причине многие API поддерживают только простой ввод-вывод.
Автор: Peter Lawrey Размещён: 15.10.2013 12:04

0 плюса

22518 Репутация автора

1) Так как ошибка вызова основной ОС, которая вызывает исключение, происходит из стека TCP, который поддерживает многопоточность, не должно быть никаких проблем.

2) Не уверен - не пробовал, но был бы удивлен, если бы была какая-либо проблема.

3) Могут быть некоторые различия в производительности. Вызов OS close () требует четырехстороннего рукопожатия с одноранговым TCP-сервером - не уверен, какая ОС поддерживает эту функцию неблокирующим образом (то же самое с connect).

4) Резьба .. или розетка. Вы должны сохранить ссылку на что-то. Поскольку вы закрываете сокет, кажется разумным сохранить ссылку на него :)

Автор: Martin James Размещён: 15.10.2013 12:09
Вопросы из категории :
32x32