简体   繁体   English

两个不同的Class实例给出相同的hashCode

[英]Two different Class instances giving same hashCode

I'm encountering a bizarre issue on a JBoss server where two classes are producing the same hashCode() . 我在JBoss服务器上遇到一个奇怪的问题,其中两个类正在生成相同的hashCode()

Class<?> cl1 = Class.forName("fqn.Class1");
Class<?> cl2 = Class.forName("fqn.Class2");
out.println(cl1.getCanonicalName());
out.println(cl2.getCanonicalName());
out.println(cl1.hashCode());
out.println(cl2.hashCode());
out.println(System.identityHashCode(cl1));
out.println(System.identityHashCode(cl2));
out.println(cl1 == cl2);
out.println(cl1.equals(cl2));
out.println(cl1.getClassLoader().equals(cl2.getClassLoader()));

Produces: 产生:

fnq.Class1
fnq.Class2
494722
494722
494722
494722
false
false
true

I normally wouldn't care, but we're using a framework that caches setters using a key that is comprised of hashcodes from the class and a property name. 我通常不会在乎,但是我们正在使用一个框架,该框架使用由类的哈希码和属性名称组成的键来缓存设置器。 It's a bad design for caching, but it's beyond my control at the moment (OGNL 3.0.6 in the latest Struts 2.3.24, see source . A newer OGNL fixes the issue, but it won't be in Struts until 2.5, currently in beta.) 这是一个不好的设计缓存,但它是我无法控制的那一刻(OGNL 3.0.6最新的Struts 2.3.24,看到 。一个新的OGNL修复的问题,但它不会在Struts中,直到2.5,目前在测试版中。)

What makes the issue somewhat bizarre to me is 使这个问题对我有些奇怪的是

  • Problem appears after several days of usage... and I'm pretty sure both class/properties are getting cached during that time. 使用几天后出现问题...而且我很确定在这段时间内两个类/属性都被缓存了。 This leads me to believe that the class instance hashcode is actually changing ... they became equal after several days. 这使我相信类实例的哈希码实际上正在发生变化 ……几天后它们变得相等。
  • We've observed the behavior in a very outdated Hotspot 1.6, and now on 1.7.0_80. 我们已经在过时的Hotspot 1.6(现在是1.7.0_80)中观察到了该行为。 Both are 32-bit builds on Sun Sparc 两者都是基于Sun Sparc的32位构建
  • JVM reports -XX:hashCode as "0" JVM将-XX:hashCode报告为“ 0”

I read that the RNG hashcode generator in Hotspot (the "0" strategy) can produce duplicates if there's racing threads, but I can't imagine classloading triggering that behavior. 我读到Hotspot中的RNG哈希码生成器(“ 0”策略)在存在竞速线程的情况下可以产生重复项,但是我无法想象类加载会触发该行为。

Does Hotspot use special hashcode handling when creating a Class instance? 创建Class实例时,Hotspot是否使用特殊的哈希码处理?

  1. java.lang.Class does not override hashCode , nor JVM handles it somehow specially. java.lang.Class不会覆盖hashCode ,JVM也不会以某种方式对其进行特殊处理。 This is just the regular identity hashCode inherited from java.lang.Object . 这只是从java.lang.Object继承的常规标识hashCode。
  2. When -XX:hashCode=0 (default in JDK 6 and JDK 7) the identity hashCode is calculated using global Park-Miller random number generator. -XX:hashCode=0 (JDK 6和JDK 7中的默认值)时,将使用全局Park-Miller随机数生成器来计算标识hashCode。 This algorithm produces unique integers with the period of 2^31-2 , so there is almost no chance that two objects have the same hashCode except for the reason below. 该算法会产生周期为2^31-2唯一整数,因此,除了以下原因之外,几乎没有机会使两个对象具有相同的hashCode。
  3. Since this algorithm relies on a global variable that is not synchronized, there is indeed a possibility that two different threads generate the same random number due to race condition (the source) . 由于此算法依赖于未同步的全局变量,因此确实有可能由于竞争条件(源)而使两个不同的线程生成相同的随机数。 This is what apparently happens in your case. 这显然是您的情况。
  4. Identity hashCode is not generated on object creation, but on the first call to hashCode method. 标识hashCode不是在对象创建时生成的,而是在首次调用hashCode方法时生成的。 So it does not matter when and how the classes are loaded. 因此,何时以及如何加载类都没有关系。 The problem can happen with any two objects if hashCode is called concurrently. 如果同时调用hashCode则任何两个对象都可能发生此问题。
  5. I suggest using -XX:hashCode=5 (default in JDK 8). 我建议使用-XX:hashCode=5 (JDK 8中的默认值)。 This option uses thread-local Xorshift RNG. 此选项使用线程本地Xorshift RNG。 It is not subject to race conditions and is also faster than Park-Miller algorithm. 它不受比赛条件的影响,并且比Park-Miller算法还快。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 两个字符串实例看起来相同,但是它们的哈希码不同 - two string instances seems same, but their hashcode are different 对于内部类的不同实例,hashCode可以是相同的吗? - hashCode can be the same for different instances of an inner class? 接口的两个完全相同的实现给出不同的.hashCode()结果 - Two exact same implementations of an interface are giving different .hashCode() results 两个具有相同哈希码但不相等的实例 - Two instances having the same hashcode but not equal 如果 hashcode() 是根据 object 的地址创建 hashcode 的,那么两个内容相同的不同对象如何创建相同的 hashcode? - If the hashcode() creates hashcode based on the address of the object, how can two different objects with same contents create the same hashcode? 在相同类的两个不同实例上定义的线程之间的通信? - Communication between threads defined on two different instances of same class? 两个工厂类以相同的条件生成不同的接口实例 - Two factory class to generate different interface instances with same condtion 为什么具有相同数据的两个不同的 HashSet 具有相同的 HashCode? - Why do two different HashSets with the same data have the same HashCode? Spring配置模拟给出两个不同的实例 - Spring configured mock giving two different instances 同一个类的两个类是否具有相同的哈希码,它们被认为是相同的吗? - Do two classes of the same class have the same hashcode and are they considered equal?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM