Java InetAddress不是线程安全的?
我们使用jdk1.8。例外情况如下:Java InetAddress不是线程安全的?,java,synchronization,thread-safety,inetaddress,Java,Synchronization,Thread Safety,Inetaddress,我们使用jdk1.8。例外情况如下: Caused by: java.lang.NullPointerException at java.net.InetAddress$Cache.put(InetAddress.java:806) at java.net.InetAddress.cacheAddresses(InetAddress.java:885) at java.net.InetAddress.getAddressesFromNameService(InetAddr
Caused by: java.lang.NullPointerException
at java.net.InetAddress$Cache.put(InetAddress.java:806)
at java.net.InetAddress.cacheAddresses(InetAddress.java:885)
at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1362)
at java.net.InetAddress.getAllByName0(InetAddress.java:1276)
at java.net.InetAddress.getAllByName(InetAddress.java:1192)
at java.net.InetAddress.getAllByName(InetAddress.java:1126)
at java.net.InetAddress.getByName(InetAddress.java:1076)
at java.net.InetSocketAddress.<init>(InetSocketAddress.java:220)
at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:451)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:546)
at sun.net.www.http.HttpClient.<init>(HttpClient.java:214)
at sun.net.www.http.HttpClient.New(HttpClient.java:326)
at sun.net.www.http.HttpClient.New(HttpClient.java:345)
...........
...........
缓存:
ublic Cache put(String host, InetAddress[] addresses) {
int policy = getPolicy();
if (policy == InetAddressCachePolicy.NEVER) {
return this;
}
// purge any expired entries
if (policy != InetAddressCachePolicy.FOREVER) {
// As we iterate in insertion order we can
// terminate when a non-expired entry is found.
LinkedList<String> expired = new LinkedList<>();
long now = System.currentTimeMillis();
for (String key : cache.keySet()) {
CacheEntry entry = cache.get(key);
806 if (entry.expiration >= 0 && entry.expiration < now) {
807 expired.add(key);
808 } else {
809 break;
}
}
for (String key : expired) {
cache.remove(key);
}
}
// create new entry and add it to the cache
// -- as a HashMap replaces existing entries we
// don't need to explicitly check if there is
// already an entry for this host.
long expiration;
if (policy == InetAddressCachePolicy.FOREVER) {
expiration = -1;
} else {
expiration = System.currentTimeMillis() + (policy * 1000);
}
828 CacheEntry entry = new CacheEntry(addresses, expiration);
829 cache.put(host, entry);
830 return this;
}
ublic缓存put(字符串主机,InetAddress[]地址){
int policy=getPolicy();
if(policy==InetAddressCachePolicy.NEVER){
归还这个;
}
//清除所有过期的条目
if(policy!=InetAddressCachePolicy.FOREVER){
//当我们按插入顺序迭代时,我们可以
//找到未过期的条目时终止。
LinkedList expired=新建LinkedList();
long now=System.currentTimeMillis();
for(字符串键:cache.keySet()){
CacheEntry=cache.get(key);
806如果(entry.expiration>=0&&entry.expiration
缓存是否有可能被系统中的其他代码损坏?您可以尝试在不同的JDK上运行代码吗?您是否能够可靠地复制它,如果是这样,它使用的是什么代码/输入?最后,如果您的帖子缺少详细信息,请不要粘贴“Stackoverflow said等”,这些不是详细信息,而是垃圾邮件。@Kayaman 1。缓存是否有可能被系统中的其他代码损坏?不,缓存由InetAddress管理,任何人都不能同时修改。2.你能试着在不同的JDK上运行代码吗?你能可靠地重现这一点吗?如果是的话,它发生在什么代码/输入上?抱歉,机器只有一个jdk版本,npe不会立即出现。我的问题是为什么这会抛出npe。缓存在InetAddress中的修改都已同步。如果您的帖子缺少详细信息,请不要粘贴“Stackoverflow said等”,对不起,为了方便起见,我复制了答案的源代码。缓存可能已损坏(例如通过反射),但可能性不大。您是否连接到许多不同的地址?这是有缺陷的行为,所以这就是这个问题的症结所在。@Kayaman是的,有几个客户。他们需要通过InetAddress获取主机的ip。确实,可能有一个线程修改缓存。但是我没有找到它。
ublic Cache put(String host, InetAddress[] addresses) {
int policy = getPolicy();
if (policy == InetAddressCachePolicy.NEVER) {
return this;
}
// purge any expired entries
if (policy != InetAddressCachePolicy.FOREVER) {
// As we iterate in insertion order we can
// terminate when a non-expired entry is found.
LinkedList<String> expired = new LinkedList<>();
long now = System.currentTimeMillis();
for (String key : cache.keySet()) {
CacheEntry entry = cache.get(key);
806 if (entry.expiration >= 0 && entry.expiration < now) {
807 expired.add(key);
808 } else {
809 break;
}
}
for (String key : expired) {
cache.remove(key);
}
}
// create new entry and add it to the cache
// -- as a HashMap replaces existing entries we
// don't need to explicitly check if there is
// already an entry for this host.
long expiration;
if (policy == InetAddressCachePolicy.FOREVER) {
expiration = -1;
} else {
expiration = System.currentTimeMillis() + (policy * 1000);
}
828 CacheEntry entry = new CacheEntry(addresses, expiration);
829 cache.put(host, entry);
830 return this;
}