Я играл с вашим кодом и заметил, что состояние прерывания потока иногда имеет значение true перед созданием сокета и false после.
Я попытался прервать поток и вызвать конструктор Socket, и поток всегда остается прерванным после этого.Я также попытался удалить отключение пула потоков, и проблема продолжала возникать.
Тогда я попытался использовать 5 разных URI, а не всегда один и тот же.И проблема никогда не случалась.
Итак, я написал эту простую программу, показывающую, что пул потоков не виновник, а сокет:
public static void main(String[] args) throws Exception {
final URI uri = new URI("http://stackoverflow.com");
for (int i = 0; i < 5; i++) {
Runnable r = new Runnable() {
@Override
public void run() {
Thread.currentThread().interrupt();
System.out.println(Thread.currentThread().isInterrupted());
try {
Socket socket = new Socket (uri.getHost(), uri.getPort() == -1 ? 80 : uri.getPort());
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().isInterrupted());
}
};
new Thread(r).start();
}
}
И действительно, когда 5 потоков создают сокет для одного хостаи порт, у 4 из них статус прерывания очищен.
Затем я попытался синхронизировать создание сокета (с одной блокировкой, но я полагаю, вы можете использовать одну блокировку на хост / порт):
synchronized(lock) {
try {
Socket socket = new Socket (uri.getHost(), uri.getPort() == -1 ? 80 : uri.getPort());
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
и ТАДА ... проблема исчезла.Я бы открыл ошибку в Oracle, чтобы сигнализировать о проблеме.