我玩过你的代码,注意到线程的中断状态有时在套接字创建之前为 true,而在创建之后为 false。
我尝试中断一个线程并调用 Socket 构造函数,但之后线程始终保持中断状态。我也尝试取消线程池的关闭,问题仍然发生。
然后我尝试使用 5 个不同的 URI,而不是始终使用相同的 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();
}
}
和 TADA...问题消失了。我会在 Oracle 中打开一个错误来表明该问题。