sun.*包内的类在开发时尽量不要使用,官网上也建议大家不要使用,可以参考https://www.oracle.com/java/technologies/faq-sun-packages.html,像eclipse之类的编译器也会对引用sun.*子包内的类给出编译错误,要想使用必须相应设置可以绕过这一限制,但是这却不是一个好的开发习惯,sun.*子包内的类很可能会在后续版本中移除,sun.misc.Hashing这个类在jdk8中就移除了,笔者为了看下jdk7中hashmap用在多线程情况下死循环的问题,将jdk7中hashmap实现拷贝出来,但是在编译时报了“sun.misc.Hashing cannot be resolved to a type”编译失败,在网上搜了很多,基本上没人提到这个问题,大部分都是sun.misc.Base64Encoder、sun.misc.Base64Decoder之类的信息,最终在eclipse使用CTRL+SHIFT+T查了下Hashing这个类,发现这个类在jdk7版本中存在,但在jdk8版本中却移除了。
PS:
1、为了代码的可移植性,尽量慎用sun包下类
2、JDK7中hashmap用在多线程中出现死循环问题就在于扩容时数据重新配置时逆序导致的,只需要将transfer方法进行下面的调整就可以避免死循环问题,这也是jdk8中数据重新分配策略:
/**
* Transfers all entries from current table to newTable.
*/
void transfer(Entry[] newTable, boolean rehash) {
//jdk7中调整策略,用在多线程中存在死循环问题
/* int newCapacity = newTable.length;
for (Entry<K,V> e : table) {
while(null != e) {
Entry<K,V> next = e.next;
if (rehash) {
e.hash = null == e.key ? 0 : hash(e.key);
}
int i = indexFor(e.hash, newCapacity); //所在散列桶序号
e.next = newTable[i]; //这边做了逆序处理,在多线程使用时会导致死循环
newTable[i] = e;
e = next;
}
}*/
int oldCap = table.length;
for (Entry<K,V> e : table) {
Entry<K,V> loHead = null, loTail = null;
Entry<K,V> hiHead = null, hiTail = null;
int i =0;
while(null != e) {
Entry<K,V> next = e.next;
if (rehash) {
e.hash = null == e.key ? 0 : hash(e.key);
}
i = e.hash & (oldCap-1);
if ((e.hash & oldCap) == 0) {//在原来的散列桶
if (loTail == null)
loHead = e;
else
loTail.next = e;
loTail = e;
}
else {//不在原来的散列桶
if (hiTail == null)
hiHead = e;
else
hiTail.next = e;
hiTail = e;
}
e = next;
}
if (loTail != null) {
loTail.next = null;
newTable[i] = loHead;
}
if (hiTail != null) {
hiTail.next = null;
newTable[i + oldCap] = hiHead;
}
}
}