java - 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(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)
...........
...........
从第 828,829 行开始,Cache 不会将null放入地图中。
但是,InetAddress在缓存地址时使用了同步。
所以不知道为什么会抛出NullPointerException。
注意,缓存是由 InetAddress 而不是用户管理的。我想知道为什么它会抛出npe。这是不可能的。
相关代码如下:
网络地址:
// InetAddress
private static void cacheAddresses(String hostname,
InetAddress[] addresses,
boolean success) {
hostname = hostname.toLowerCase();
synchronized (addressCache) {
cacheInitIfNeeded();
if (success) {
885 addressCache.put(hostname, addresses);
886 } else {
887 negativeCache.put(hostname, addresses);
}
}
}
缓存:
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;
}
解决方案
推荐阅读
- python - Destiny2 API - POST Transfer Item 总是返回 DestinyItemNotFound
- r - 加权平均误差。为什么找不到专栏?
- javascript - 如何防止调整 Javascript 窗口的大小和最大化
- python - 使用 UDF 在 pyspark 中对生成的 DataFrame 进行排序
- javascript - 有没有办法存储以前的html,如果json有任何变化,那么只更新html中的那些变化?
- mongodb - MongoDB CREATE SCHEMA 等效项
- flutter - Android 模拟器抛出系统 UI 无响应
- wpf - WPF如何为两个不同菜单的MenuItem Popup设置不同的样式
- excel - 字符串数据透视表excel
- shopify - Shopify 订单编辑:XXX 未添加,因为它已经在订单上