OpenHFT / Zero-Allocation-Hashing

Zero-allocation hashing for Java
Apache License 2.0
787 stars 136 forks source link

Fix static initialization deadlock (Fixes #53) #70

Closed edrevo closed 2 years ago

edrevo commented 2 years ago

There is a dependency cycle in the static initializers of Utils and UnsafeAccess which can cause a deadlock if both classes are static-initialized in different threads.

Specifically, the cycle is the one shown by these stack traces:

Thread 1

   java.lang.Thread.State: RUNNABLE
    at net.openhft.hashing.CompactLatin1CharSequenceAccess.<clinit>(CompactLatin1CharSequenceAccess.java:83)
    - waiting on the Class initialization monitor for net.openhft.hashing.UnsafeAccess
    at net.openhft.hashing.ModernCompactStringHash.<clinit>(ModernCompactStringHash.java:14)
    at net.openhft.hashing.Util.<clinit>(Util.java:41)

Thread 2

   java.lang.Thread.State: RUNNABLE
    at net.openhft.hashing.UnsafeAccess.<clinit>(UnsafeAccess.java:30)
    - waiting on the Class initialization monitor for net.openhft.hashing.Util

This is due to the NATIVE_LITTLE_ENDIAN field. This PR moves this field to the Primitives class, which does not depend on any other class in the project, to avoid this deadlock.