Re: Write-to-disk cache via WeakReferences?

Discussion in 'Java' started by Paul J. Lucas, Aug 3, 2005.

  1. Thomas Hawtin <> wrote:

    > The situation in code looks something like this (only with better names):
    >
    > public class Resource {
    > public void doStuff() { ... }
    > }
    > public class Proxy {
    > private final Resource target;
    > Proxy(Resource target) {
    > if (target == null) {
    > throw new NullPointerException();
    > }
    > this.target = target;
    > }
    > public void doStuff() {
    > target.doStuff();
    > }
    > }
    > class Ref extends Reference<Proxy> {
    > private final Resource resource;
    > public Ref(Proxy proxy, Resource resource) {
    > super(proxy);
    > this.resource = resource;
    > }
    > Resource getResource() {
    > return resource;
    > }
    > }
    > class Saver implements Runnable {
    > ...
    > public void run() {
    > for (;;) {
    > Ref ref = (Ref)queue.remove();
    > saveToDisk(ref.getResource());
    > }
    > }
    > }


    Where did the SoftReference go?
    You never create/pass a ReferenceQueue anywhere.
    What about my code below?

    - Paul


    public interface StrongReference {
    Object getAndClearStrong();
    }

    public class SoftStrongReference extends SoftReference
    implements StrongReference {

    public SoftStrongReference( Object referrent, ReferenceQueue refQ ) {
    super( new Sacrifice(), refQ );
    m_referrent = referrent;
    }

    public Object getAndClearStrong() {
    final Object temp = m_referrent;
    m_referrent = null;
    return temp;
    }

    private static final class Sacrifice {
    }

    private Object m_referrent;
    }

    public interface ObjectSaver {
    void save( Object obj );
    }

    public class ReferenceQueueManager extends Thread {

    public ReferenceQueueManager( ObjectSaver saver ) {
    setDaemon( true );
    m_saver = saver;
    m_refQ = new ReferenceQueue();
    }

    public void kill() {
    m_killed = true;
    interrupt();
    }

    public void run() {
    while ( !m_killed ) {
    try {
    final StrongReference ref = (StrongReference)m_refQ.remove();
    m_saver.save( ref.getAndClearStrong() );
    }
    catch ( InterruptedException e ) {
    // do nothing
    }
    }
    }

    private boolean m_killed;
    private final ObjectSaver m_saver;
    private final ReferenceQueue m_refQ;
    }
    Paul J. Lucas, Aug 3, 2005
    #1
    1. Advertising

  2. Paul J. Lucas wrote:
    > Thomas Hawtin <> wrote:
    >
    >
    >>The situation in code looks something like this (only with better names):
    >>
    >>public class Resource {
    >> public void doStuff() { ... }
    >>}
    >>public class Proxy {
    >> private final Resource target;
    >> Proxy(Resource target) {
    >> if (target == null) {
    >> throw new NullPointerException();
    >> }
    >> this.target = target;
    >> }
    >> public void doStuff() {
    >> target.doStuff();
    >> }
    >>}
    >>class Ref extends Reference<Proxy> {

    ^^^^^^^^^SoftReference
    >> private final Resource resource;
    >> public Ref(Proxy proxy, Resource resource) {

    ^, ReferenceQueue queue
    >> super(proxy);

    ^, queue
    >> this.resource = resource;
    >> }
    >> Resource getResource() {
    >> return resource;
    >> }
    >>}
    >>class Saver implements Runnable {
    >> ...
    >> public void run() {
    >> for (;;) {
    >> Ref ref = (Ref)queue.remove();
    >> saveToDisk(ref.getResource());
    >> }
    >> }
    >>}

    >


    > Where did the SoftReference go?
    > You never create/pass a ReferenceQueue anywhere.


    Typod out (more or less).

    > public class SoftStrongReference extends SoftReference
    > implements StrongReference {
    >
    > public SoftStrongReference( Object referrent, ReferenceQueue refQ ) {
    > super( new Sacrifice(), refQ );
    > m_referrent = referrent;
    > }


    > final StrongReference ref = (StrongReference)m_refQ.remove();
    > m_saver.save( ref.getAndClearStrong() );


    Sacrifice is up for GC immediately. Therefore if you're still using the
    resource it may be persisted whilst still in use.

    Neither code refereshes the soft reference, so the GC will treat it as
    if it is unused. In my code Proxy could hold a (strong) reference to
    Ref<Proxy> and prod it from time to time..

    Tom Hawtin
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
    Thomas Hawtin, Aug 3, 2005
    #2
    1. Advertising

  3. Paul J. Lucas

    Joan Guest

    "Thomas Hawtin" <> wrote in message
    news:42f10a79$0$14660$...
    > Paul J. Lucas wrote:
    >> Thomas Hawtin <> wrote:
    >>
    >>
    >>>The situation in code looks something like this (only with
    >>>better names):
    >>>
    >>>public class Resource {

    <snip>

    I don't quite see the value of this technique. Suppose you get a
    handle
    to an Integer object. It's just a number. You have no idea what
    the
    significance is.
    Joan, Aug 3, 2005
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Indbond
    Replies:
    10
    Views:
    534
    John C. Bollinger
    Apr 23, 2004
  2. Paul J. Lucas

    Write-to-disk cache via WeakReferences?

    Paul J. Lucas, Jul 23, 2005, in forum: Java
    Replies:
    6
    Views:
    439
    Paul J. Lucas
    Jul 25, 2005
  3. Paul J. Lucas
    Replies:
    5
    Views:
    417
  4. Ian Pilcher
    Replies:
    7
    Views:
    392
    Mike Schilling
    Jan 19, 2006
  5. Replies:
    12
    Views:
    521
    santosh
    Nov 15, 2006
Loading...

Share This Page