Class SharedObject

  • All Implemented Interfaces:
    java.lang.Cloneable
    Direct Known Subclasses:
    CollationSettings

    public class SharedObject
    extends java.lang.Object
    implements java.lang.Cloneable
    Base class for shared, reference-counted, auto-deleted objects. Java subclasses are mutable and must implement clone().

    In C++, the SharedObject base class is used for both memory and ownership management. In Java, memory management (deletion after last reference is gone) is up to the garbage collector, but the reference counter is still used to see whether the referent is the sole owner.

    Usage:

     class S extends SharedObject {
         public clone() { ... }
     }
    
     // Either use the nest class Reference (which costs an extra allocation),
     // or duplicate its code in the class that uses S
     // (which duplicates code and is more error-prone).
     class U {
         // For read-only access, use s.readOnly().
         // For writable access, use S ownedS = s.copyOnWrite();
         private SharedObject.Reference<S> s;
         // Returns a writable version of s.
         // If there is exactly one owner, then s itself is returned.
         // If there are multiple owners, then s is replaced with a clone,
         // and that is returned.
         private S getOwnedS() {
             return s.copyOnWrite();
         }
         public U clone() {
             ...
             c.s = s.clone();
             ...
         }
     }
    
     class V {
         // For read-only access, use s directly.
         // For writable access, use S ownedS = getOwnedS();
         private S s;
         // Returns a writable version of s.
         // If there is exactly one owner, then s itself is returned.
         // If there are multiple owners, then s is replaced with a clone,
         // and that is returned.
         private S getOwnedS() {
             if(s.getRefCount() > 1) {
                 S ownedS = s.clone();
                 s.removeRef();
                 s = ownedS;
                 ownedS.addRef();
             }
             return s;
         }
         public U clone() {
             ...
             s.addRef();
             ...
         }
         protected void finalize() {
             ...
             if(s != null) {
                 s.removeRef();
                 s = null;
             }
             ...
         }
     }
     
    Either use only Java memory management, or use addRef()/removeRef(). Sharing requires reference-counting. TODO: Consider making this more widely available inside ICU, or else adopting a different model.
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      static class  SharedObject.Reference<T extends SharedObject>
      Similar to a smart pointer, basically a port of the static methods of C++ SharedObject.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private java.util.concurrent.atomic.AtomicInteger refCount  
    • Constructor Summary

      Constructors 
      Constructor Description
      SharedObject()
      Initializes refCount to 0.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void addRef()
      Increments the number of references to this object.
      SharedObject clone()
      Initializes refCount to 0.
      void deleteIfZeroRefCount()  
      int getRefCount()
      Returns the reference counter.
      void removeRef()
      Decrements the number of references to this object, and auto-deletes "this" if the number becomes 0.
      • Methods inherited from class java.lang.Object

        equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • refCount

        private java.util.concurrent.atomic.AtomicInteger refCount
    • Constructor Detail

      • SharedObject

        public SharedObject()
        Initializes refCount to 0.
    • Method Detail

      • clone

        public SharedObject clone()
        Initializes refCount to 0.
        Overrides:
        clone in class java.lang.Object
      • addRef

        public final void addRef()
        Increments the number of references to this object. Thread-safe.
      • removeRef

        public final void removeRef()
        Decrements the number of references to this object, and auto-deletes "this" if the number becomes 0. Thread-safe.
      • getRefCount

        public final int getRefCount()
        Returns the reference counter. Uses a memory barrier.
      • deleteIfZeroRefCount

        public final void deleteIfZeroRefCount()