结论在文章结尾,我们先看过程
示例程序:
public static void main(String[] args) throws Exception {
for (int i = 0; i < 100; i++) {
InetAddress addresses = InetAddress.getByName("www.baidu.com");
System.out.println(addresses.getHostAddress());
System.out.println(addresses.getHostName());
Thread.sleep(1000);
}
}
本地添加一条host:127.0.0.1 www.baidu.com
发现并没立即生效,大概30s之后生效的。
看了下源码,是从InetAddressHolder去拿的,以为这里做了文章。
image.png
但是发现InetAddress和InetAddressHolder都是一起改的,并没有什么因果关系
image.png
那重点就回到有的时候不改,不改的时候走的逻辑就是我们关注的地方了。
image.png
看到是用了cache的。那么cache什么情况下失效呢?
image.png
可以看到CacheEntry是有个expiration过期时间字段的。
image.png
过期时间是在哪里设置的呢?我们直接用这个字段来断点
image.png
看到是默认缓存30s,是在put进缓存的时候设置的。
这个30s是在哪里设置的呢,看到是InetAddressCachePolicy的cachePolicy字段来决定的。debug这个字段,看看是哪里修改的
image.png
可以看到默认是30s。
所以如果要禁止缓存的话,可以
1. 设置java.security.Security.setProperty("networkaddress.cache.ttl", "0");
2 jvm启动参数中设置-Dsun.net.inetaddr.ttl=0
当然我们也可以通过反射的方式,强行清空缓存:
public static void clearCache() throws NoSuchFieldException, IllegalAccessException {
Field field = java.net.InetAddress.class.getDeclaredField("addressCache");
field.setAccessible(true);
Object addressCache = field.get(null);
Field cacheMapField = addressCache.getClass().getDeclaredField("cache");
cacheMapField.setAccessible(true);
Map cacheMap = (Map) cacheMapField.get(addressCache);
cacheMap.clear();
}
网友评论