Тайм-аут сокета не учитывается для нескольких потоков в Java? - PullRequest
0 голосов
/ 03 мая 2011

У меня есть Java-программа, которая порождает 4 потока.В каждом потоке у меня есть несколько тайм-аутов сокетов.Однако кажется, что эти тайм-ауты не соблюдаются, т.е. функция readLine() может блокироваться на более длительный период времени.

Мне нужно следующее поведение: если я установлю тайм-аут сокета на 300 мс, то я хочу, чтобы функция readLine() возвращалась в течение 300 мс с момента вызова readLine() (то есть основного вызова select), не важно что.Я понимаю, что планировщик ОС будет переводить потоки в спящий режим при совместном использовании процессора, но есть ли в Java какой-либо способ заставить потоки всегда просыпаться, чтобы обеспечить такое поведение?Или это просто неправильный способ думать при многопоточном программировании?

В идеале, поскольку я порождаю 4 потока и работаю на 6-ядерном компьютере, каждый поток должен иметь возможность получать свой собственный ЦП и работать параллельно, и уважать время ожидания выбора ... но это возможнослишком много, чтобы ожидать ...

PS: я действительно использую Thread.interrupt (), чтобы гарантировать, что каждый из моих потоков завершится в течение определенного времени (я проверяю время, прошедшее в главном потоке, и прерываюдочерние темы, если это было слишком долго).В каждом из моих потоков я подключаюсь к (разному) серверу, делаю запрос и жду ответа.Я не знаю, как долго ответ будет.Поэтому я продолжаю вызывать метод readLine(), пока не истечет время ожидания SocketTimeoutException.Я устанавливаю тайм-аут в 300 мс, так как ожидаю, что сервер начнет отвечать в течение этого времени.Причина, по которой я хочу применить этот тайм-аут, заключается в том, что сервер ведет себя широковещательно и отправляет ответы на запрос от одного клиента всем клиентам.Поэтому, если у меня нет тайм-аута, я буду продолжать получать данные в ответ на запросы некоторых других клиентов.

Ответы [ 2 ]

1 голос
/ 03 мая 2011

Если я действительно понял вашу проблему, вы всегда можете попытаться вызвать Thread.interrupt() в потоке, который выполняет операцию readLine(). Поскольку вы не предоставили никакого кода, я оставляю эту ссылку для чтения. Он общий, но предоставляет достаточно информации о прерывании потоков.

Эти две ссылки также могут быть вам полезны: Как убить поток в Java? и Как быстро и чисто прервать поток в Java? .

Что касается вашего вопроса о планировщике ОС, вы должны знать, что в ОС общего назначения у вас нет полного контроля над тем, как ОС планирует задачи. Например, в Linux прерывания являются задачами с наивысшим приоритетом, а затем существуют политики планирования, которые позволяют наложить «некоторый» детерминизм на то, как планируются задачи. В Java вы можете использовать метод setPriority() для изменения приоритета потока, но на самом деле это то же самое, что и команда nice, и все же вы не получаете никаких гарантий, что этот поток будет запланирован заранее. других потоков ОС.

Надеюсь, это поможет.

0 голосов
/ 03 мая 2011

Вы делаете здесь неправильные предположения:

  • , что время ожидания будет ровно 300 мс.На самом деле время ожидания составляет не менее 300 мс.
  • Планировщик ОС ничего не делает (вместо того, чтобы планировать процессы Java) в потоках Java.
  • , имеющий 6 ядер, не означает, что каждый из ваших потоков будет работать по отдельностиядро, невозможно связать thread-> core на java
  • для последнего, вы считаете, что на jvm работают только ваши 4 потока, но на самом деле там больше потоков, например, поток сборщика мусора(s).

Задавая ваш вопрос: «есть ли в Java какой-либо способ заставить потоки всегда просыпаться, чтобы обеспечить такое поведение?» Да, в зависимости от того, каков ваш код, еслиthread равен thread.sleep () , вы можете использовать thread.interrupt () (для readline () его использует) и обрабатывать InterruptException или, если они object.wait() , вы можете использовать object.notify () или object.notifyAll () .

...