public ClassInfo getClassInfo( Class type ) {        
        //return cache.getUnchecked(type); // Guava version
 
        // More complicated without guava
        lock.readLock().lock();
        try {
            ClassInfo result = cache.get(type);
            if( result != null ) {
                return result;
            }
            // Else we need to create it and store it, so grab the write lock.
            lock.readLock().unlock();
            lock.writeLock().lock();
            try {
                // Note: it's technically possible that a race with another thread
                // asking for the same class already created one between our read unlock
                // and our write lock.  No matter as it's cheap to create one and does
                // no harm.  Code is simpler without the double check.
                result = new ClassInfo((short)nextClassId.getAndIncrement(), type);
                cache.put(type, result);
                
                // Re-grab the read lock before leaving... kind of unnecessary, but
                // it makes the method cleaner and widens the gap of lock races.
                // Downgrading a write lock to read is ok.
                lock.readLock().lock();
                
                return result;
            } finally {
                // Unlock the write lock while still holding onto the read lock.
                lock.writeLock().unlock();
            }
        } finally {
            lock.readLock().unlock();
        }
    }
Internal registry of shared types and their ClassInfo and MethodInfo
 objects.

 @author    Paul Speed
jme3-networking/src/main/java/com/jme3/network/service/rmi/ClassInfoRegistry.java