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.
| Modifier and Type | Class 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. |
| Modifier and Type | Field and Description |
|---|---|
| private AtomicInteger |
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| public final void | |
| public SharedObject | |
| public final void | |
| public final int | |
| public final void | removeRef()
Decrements the number of references to this object, and auto-deletes "this" if the number becomes 0. |
| refCount | back to summary |
|---|---|
| private AtomicInteger refCount | |
| SharedObject | back to summary |
|---|---|
| public SharedObject() Initializes refCount to 0. | |
| addRef | back to summary |
|---|---|
| public final void addRef() Increments the number of references to this object. Thread-safe. | |
| clone | back to summary |
|---|---|
| public SharedObject clone() Overrides java. Initializes refCount to 0.
| |
| deleteIfZeroRefCount | back to summary |
|---|---|
| public final void deleteIfZeroRefCount() | |
| getRefCount | back to summary |
|---|---|
| public final int getRefCount() Returns the reference counter. Uses a memory barrier. | |
| removeRef | back 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. | |