Name: nt126004 Date: 04/14/2003
A DESCRIPTION OF THE REQUEST :
I would to have an additional subclass of java.lang.ref.Reference called (for example) SaveableReference that has the following property: when the garbage collector determines that an object is reachable through a SaveableReference, but not through any normal references, the SaveableReference is placed on the associated ReferenceQueue. The difference between this and WeakReference is that the referred-to object is NOT finalized and is still obtainable through the get() method. When placed on a ReferenceQueue, a flag should be set to make the reference strong so the it isn't reclaimed over and over again while it is sitting on the ReferenceQueue. This flag can be subsequently cleared by the application.
The SaveableReference is a stronger reference type than any other in the java.lang.ref package.
If the SaveableReference is not associated with a ReferenceQueue, then it behaves like WeakReference.
JUSTIFICATION :
The purpose of this feature is to allow various types of resource pools to interact with the GC. A concrete example that motivated this RFE was a connection pooling scheme for a client/server protocol that I was implementing. See below for a simplified example. I wanted to be able to hand out connections that could be automatically reused if the client "leaked" the connection. I expected weak references would provide this capability, but I was mistaken. I was forced to design some rather complex workarounds instead.
---------- BEGIN SOURCE ----------
A simple example of why this is useful. (I deliberately ignored
thread synchronization to make it easier to read).
class ConnectionPool {
LinkedList freeConnections = new LinkedList();
LinkedList allConnectionRefs = new LinkedList();
ReferenceQueue refq = new ReferenceQueue();
ConnectionPool() {
new ReclaimThread().start();
}
Connection getConnection() {
if (freeConnections.size() > 0)
return (Connection) freeConnections.removeHead();
else
return newConnection();
}
Connection newConnection() {
Connection c = new Connection(...);
allConnectionRefs.add(new SaveableReference(c, refq));
}
class ReclaimThread extends Thread {
public void run() {
while(true) {
SaveableReference r = refq.remove(); // blocking
freeConnections.add(r.get()); // return connection to free list
r.clearStrongFlag(); // reset the SaveableReference
}
}
}
}
---------- END SOURCE ----------
(Review ID: 184016)
======================================================================