Есть много вещей, которые могут вызвать это, но похоже, что вы, вероятно, испытываете обратное давление на уровне TCP.
Обычно, когда вы отправляете данные в сокет, они просто буферизируются, и отправляющий вызов (в вашем случае println()
и flush()
) может вернуться до того, как данные действительно будут отправлены в сеть. Может случиться так, что все ваши предыдущие записи в этом сокете были просто помещены в локальный SO_SNDBUF , и вы просто заполнили его.
(1) Можете ли вы отследить это, используя tcpdump или Wireshark, и найти точное соединение, которое зависает (я знаю, что это становится трудно со многими соединениями)? Изучение размера окна TCP во время зависания вашей программы расскажет вам больше о том, блокируете ли вы в самой Java или на сетевом уровне.
(2) Сбросьте стопку и разместите ее здесь. Сокеты Java имеют внутреннюю блокировку, предотвращающую одновременную запись в них двух потоков. Вы уверены, что только один поток обращается к этому сокету в тот момент, когда вы пытаетесь написать?
Вы определенно хотите попробовать сделать
$ jstack <PID>
когда он заморожен, чтобы точно увидеть, где он висит, и если поток записи пытается получить какие-либо блокировки.