KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > enode > TimedSoftReference


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.enode;
21
22 import java.lang.ref.SoftReference JavaDoc;
23 import java.util.Map JavaDoc;
24
25 import org.openide.util.*;
26
27 /**
28  * Copied from org.openide.util where this class is not public.
29  *
30  * A soft reference which is held strongly for a while after last access.
31  * Lifecycle:
32  * <ol>
33  * <li>Created. Referent held strongly. A task is scheduled into the request
34  * processor for some time in the future (currently 30 seconds).</li>
35  * <li>Expired. After the timeout, the reference switches to a normal soft
36  * reference.</li>
37  * <li>Touched. If the value is accessed before it is garbage collected,
38  * whether the reference is expired or not, the reference is "touched".
39  * This means that the referent is again held strongly and the timeout
40  * is started from scratch.</li>
41  * <li>Dead. If after expiry there is no access before the next full GC cycle,
42  * the GC algorithm may reclaim the reference. In this case the reference
43  * of course dies. As a bonus, it will try to remove itself as the value
44  * from a map of your choice, to make it convenient to use these references
45  * as values in a caching map without leaking memory for the key.</li>
46  * </ol>
47  * @author Jesse Glick
48  */

49 public final class TimedSoftReference extends SoftReference JavaDoc implements Runnable JavaDoc {
50     
51     private static final int TIMEOUT = 30000;
52     
53     private static final RequestProcessor RP = new RequestProcessor("enode-TimedSoftReference"); // NOI18N
54

55     private RequestProcessor.Task task;
56     
57     private Object JavaDoc o;
58     
59     private final Map JavaDoc m;
60     
61     private final Object JavaDoc k;
62     
63     /** Time when the object was last time touched */
64     private long touched;
65     
66     /**
67      * Create a soft reference with timeout.
68      * The supplied map serves double duty as a synchronization lock
69      * for the reference's state changes.
70      * @param o the referent
71      * @param m a map in which this reference may serve as a value
72      * @param k the key whose value in <code>m</code> may be this reference
73      */

74     public TimedSoftReference(Object JavaDoc o, Map JavaDoc m, Object JavaDoc k) {
75         super(o, Utilities.activeReferenceQueue());
76         this.o = o;
77         this.m = m;
78         this.k = k;
79         task = RP.create(this);
80         task.schedule(TIMEOUT);
81     }
82     
83     public void run() {
84         synchronized (m) {
85             if (o != null) {
86                 //System.err.println("Expire " + k);
87
// how long we've really been idle
88
long unused = System.currentTimeMillis() - touched;
89                 if (unused > TIMEOUT/2) {
90                     o = null;
91                     touched = 0;
92                 } else {
93                     task.schedule(TIMEOUT - (int)unused);
94                 }
95             } else {
96                 // clean up map ref, we are dead
97
//System.err.println("Die " + k);
98
m.remove(k);
99             }
100         }
101     }
102     
103     public Object JavaDoc get() {
104         synchronized (m) {
105             if (o == null) {
106                 o = super.get();
107             }
108             if (o != null) {
109                 // touch me
110
//System.err.println("Touch " + k);
111
if (touched == 0) {
112                     task.schedule(TIMEOUT);
113                 }
114                 touched = System.currentTimeMillis();
115                 return o;
116             } else {
117                 return null;
118             }
119         }
120     }
121     
122 }
123
Popular Tags