Top Description Inners Fields Constructors Methods
com.ibm.icu.impl.coll

public Class SharedObject

extends Object
implements Cloneable
Class Inheritance
All Implemented Interfaces
java.lang.Cloneable
Known Direct Subclasses
com.ibm.icu.impl.coll.CollationSettings
Imports
java.util.concurrent.atomic.AtomicInteger, com.ibm.icu.util.ICUCloneNotSupportedException

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 and Inner Type Summary

Modifier and TypeClass and Description
public static class
SharedObject.Reference<T extends SharedObject>

Similar to a smart pointer, basically a port of the static methods of C++ SharedObject.

Field Summary

Modifier and TypeField and Description
private AtomicInteger

Constructor Summary

AccessConstructor and Description
public
SharedObject()

Initializes refCount to 0.

Method Summary

Modifier and TypeMethod and Description
public final void
addRef()

Increments the number of references to this object.

public SharedObject
clone()

Overrides java.lang.Object.clone.

Initializes refCount to 0.
public final void
public final int
getRefCount()

Returns the reference counter.

public final void
removeRef()

Decrements the number of references to this object, and auto-deletes "this" if the number becomes 0.

Inherited from java.lang.Object:
equalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

refCountback to summary
private AtomicInteger refCount

Constructor Detail

SharedObjectback to summary
public SharedObject()

Initializes refCount to 0.

Method Detail

addRefback to summary
public final void addRef()

Increments the number of references to this object. Thread-safe.

cloneback to summary
public SharedObject clone()

Overrides java.lang.Object.clone.

Initializes refCount to 0.

Returns:SharedObject

Doc from java.lang.Object.clone.

a clone of this instance.

Annotations
@Override
deleteIfZeroRefCountback to summary
public final void deleteIfZeroRefCount()
getRefCountback to summary
public final int getRefCount()

Returns the reference counter. Uses a memory barrier.

removeRefback to summary
public final void removeRef()

Decrements the number of references to this object, and auto-deletes "this" if the number becomes 0. Thread-safe.

com.ibm.icu.impl.coll back to summary

public final Class SharedObject.Reference<T extends com.ibm.icu.impl.coll.SharedObject>

extends Object
implements Cloneable
Class Inheritance
All Implemented Interfaces
java.lang.Cloneable

Similar to a smart pointer, basically a port of the static methods of C++ SharedObject.

Field Summary

Modifier and TypeField and Description
private T

Constructor Summary

AccessConstructor and Description
public
Reference(T r)

Method Summary

Modifier and TypeMethod and Description
public void
public SharedObject.Reference<T>
clone()

Overrides java.lang.Object.clone.

Creates and returns a copy of this object.
public T
copyOnWrite()

Returns a writable version of the reference.

protected void
finalize()

Overrides java.lang.Object.finalize.

Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.
public T
Inherited from java.lang.Object:
equalsgetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

refback to summary
private T ref

Constructor Detail

Referenceback to summary
public Reference(T r)

Method Detail

clearback to summary
public void clear()
cloneback to summary
public SharedObject.Reference<T> clone()

Overrides java.lang.Object.clone.

Doc from java.lang.Object.clone.

Creates and returns a copy of this object. The precise meaning of "copy" may depend on the class of the object. The general intent is that, for any object x, the expression:

x.clone() != x
will be true, and that the expression:
x.clone().getClass() == x.getClass()
will be true, but these are not absolute requirements. While it is typically the case that:
x.clone().equals(x)
will be true, this is not an absolute requirement.

By convention, the returned object should be obtained by calling super.clone. If a class and all of its superclasses (except Object) obey this convention, it will be the case that x.clone().getClass() == x.getClass().

By convention, the object returned by this method should be independent of this object (which is being cloned). To achieve this independence, it may be necessary to modify one or more fields of the object returned by super.clone before returning it. Typically, this means copying any mutable objects that comprise the internal "deep structure" of the object being cloned and replacing the references to these objects with references to the copies. If a class contains only primitive fields or references to immutable objects, then it is usually the case that no fields in the object returned by super.clone need to be modified.

Returns:SharedObject.Reference<T>

a clone of this instance.

Annotations
@SuppressWarnings:unchecked
@Override
copyOnWriteback to summary
public T copyOnWrite()

Returns a writable version of the reference. If there is exactly one owner, then the reference itself is returned. If there are multiple owners, then the reference is replaced with a clone, and that is returned.

finalizeback to summary
protected void finalize() throws Throwable

Overrides java.lang.Object.finalize.

Doc from java.lang.Object.finalize.

Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. A subclass overrides the finalize method to dispose of system resources or to perform other cleanup.

When running in a Java virtual machine in which finalization has been disabled or removed, the garbage collector will never call finalize(). In a Java virtual machine in which finalization is enabled, the garbage collector might call finalize only after an indefinite delay.

The general contract of finalize is that it is invoked if and when the Java virtual machine has determined that there is no longer any means by which this object can be accessed by any thread that has not yet died, except as a result of an action taken by the finalization of some other object or class which is ready to be finalized. The finalize method may take any action, including making this object available again to other threads; the usual purpose of finalize, however, is to perform cleanup actions before the object is irrevocably discarded. For example, the finalize method for an object that represents an input/output connection might perform explicit I/O transactions to break the connection before the object is permanently discarded.

The finalize method of class Object performs no special action; it simply returns normally. Subclasses of Object may override this definition.

The Java programming language does not guarantee which thread will invoke the finalize method for any given object. It is guaranteed, however, that the thread that invokes finalize will not be holding any user-visible synchronization locks when finalize is invoked. If an uncaught exception is thrown by the finalize method, the exception is ignored and finalization of that object terminates.

After the finalize method has been invoked for an object, no further action is taken until the Java virtual machine has again determined that there is no longer any means by which this object can be accessed by any thread that has not yet died, including possible actions by other objects or classes which are ready to be finalized, at which point the object may be discarded.

The finalize method is never invoked more than once by a Java virtual machine for any given object.

Any exception thrown by the finalize method causes the finalization of this object to be halted, but is otherwise ignored.

Annotations
@Override
Exceptions
Throwable:
the Exception raised by this method
readOnlyback to summary
public T readOnly()