Я думаю, что нашел источник своих проблем!Я использую одну модель потока на клиента, но я запускаю свои тесты локально, т.е. на одной машине, что означает, что все они имеют один и тот же IP!Таким образом, каждому клиенту назначается один и тот же IP с сервером!Я предполагаю, что это приводит к тому, что сервер и клиенты различаются только по номеру порта, но поскольку каждый клиент сопоставлен с отдельным локальным портом для каждого соединения с сервером, сервер не должен блокироваться.Я подтвердил, что каждый клиент и сервер используют разные операции ввода-вывода (сравниваемые ссылки), и я обертываю их сокеты с помощью <Input/Output>Stream
s до BufferedReader
s & PrintWriter
s, но все же, когда клиент зависает, все другие клиенты тоже зависают (поэтомуможет быть каналы ввода / вывода действительно одинаковые ???)!Я проверю это на другой машине и проверю результаты обратно с вами!:)
РЕДАКТИРОВАТЬ: Подтверждено ошибочное поведение.Кажется, что даже с удаленными клиентами, если один зависает, другие клиенты, кажется, тоже зависают!: /Не знаю, но я полон решимости это исправить.Просто это довольно странно, так как я почти уверен, что использую один поток на клиента (операции ввода-вывода отличаются, сокеты клиентов различаются, IP-адреса не являются проблемой, я даже сопоставляю каждого клиента на сервере с локальным портом моеговыбор ...)Может быть, я переключусь на NIO, если не найду решение достаточно скоро.
РЕШЕНИЕ : Решил проблему!Казалось, что ExecutorService
должен быть запущен в отдельном потоке, иначе, если ввод / вывод на клиенте заблокирован, все операции ввода / вывода будут блокироваться!Это странно, учитывая тот факт, что я пробовал и Executors.newFixedThreadPool(<nThreads>);
, и Executors.newCachedThreadPool();
, и действия клиента (также известные как операции ввода-вывода) должны выполняться в новом потоке для каждого клиента.В любом случае я использовал метод и обернул вызовы, чтобы каждое клиентское учреждение использовало final ExecutorService baseWorker = Executors.newSingleThreadExecutor();
, и каждый раз явно создавал новый поток, используя <Thread instance>.start();
, чтобы каждый поток работал в фоновом режиме:)