KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tomcat > util > threads > Expirer


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.tomcat.util.threads;
18
19 import org.apache.tomcat.util.buf.TimeStamp;
20
21 /**
22  * Expire unused objects.
23  *
24  */

25 public final class Expirer implements ThreadPoolRunnable
26 {
27     
28     private static org.apache.commons.logging.Log log=
29         org.apache.commons.logging.LogFactory.getLog(Expirer.class );
30     
31     // We can use Event/Listener, but this is probably simpler
32
// and more efficient
33
public static interface ExpireCallback {
34     public void expired( TimeStamp o );
35     }
36     
37     private int checkInterval = 60;
38     private Reaper reaper;
39     ExpireCallback expireCallback;
40
41     public Expirer() {
42     }
43
44     // ------------------------------------------------------------- Properties
45
public int getCheckInterval() {
46     return checkInterval;
47     }
48
49     public void setCheckInterval(int checkInterval) {
50     this.checkInterval = checkInterval;
51     }
52
53     public void setExpireCallback( ExpireCallback cb ) {
54     expireCallback=cb;
55     }
56     
57     // -------------------- Managed objects --------------------
58
static final int INITIAL_SIZE=8;
59     TimeStamp managedObjs[]=new TimeStamp[INITIAL_SIZE];
60     TimeStamp checkedObjs[]=new TimeStamp[INITIAL_SIZE];
61     int managedLen=managedObjs.length;
62     int managedCount=0;
63     
64     public void addManagedObject( TimeStamp ts ) {
65     synchronized( managedObjs ) {
66         if( managedCount >= managedLen ) {
67         // What happens if expire is on the way ? Nothing,
68
// expire will do it's job on the old array ( GC magic )
69
// and the expired object will be marked as such
70
// Same thing would happen ( and did ) with Hashtable
71
TimeStamp newA[]=new TimeStamp[ 2 * managedLen ];
72         System.arraycopy( managedObjs, 0, newA, 0, managedLen);
73         managedObjs = newA;
74         managedLen = 2 * managedLen;
75         }
76         managedObjs[managedCount]=ts;
77         managedCount++;
78     }
79     }
80
81     public void removeManagedObject( TimeStamp ts ) {
82     for( int i=0; i< managedCount; i++ ) {
83         if( ts == managedObjs[i] ) {
84         synchronized( managedObjs ) {
85             managedCount--;
86             managedObjs[ i ] = managedObjs[managedCount];
87                     managedObjs[managedCount] = null;
88         }
89         return;
90         }
91     }
92     }
93     
94     // --------------------------------------------------------- Public Methods
95

96     public void start() {
97     // Start the background reaper thread
98
if( reaper==null) {
99         reaper=new Reaper("Expirer");
100         reaper.addCallback( this, checkInterval * 1000 );
101     }
102     
103     reaper.startReaper();
104     }
105
106     public void stop() {
107     reaper.stopReaper();
108     }
109
110
111     // -------------------------------------------------------- Private Methods
112

113     // ThreadPoolRunnable impl
114

115     public Object JavaDoc[] getInitData() {
116     return null;
117     }
118
119     public void runIt( Object JavaDoc td[] ) {
120     long timeNow = System.currentTimeMillis();
121     if( log.isTraceEnabled() ) log.trace( "Checking " + timeNow );
122     int checkedCount;
123     synchronized( managedObjs ) {
124         checkedCount=managedCount;
125         if(checkedObjs.length < checkedCount)
126         checkedObjs = new TimeStamp[managedLen];
127         System.arraycopy( managedObjs, 0, checkedObjs, 0, checkedCount);
128     }
129     for( int i=0; i< checkedCount; i++ ) {
130         TimeStamp ts=checkedObjs[i];
131         checkedObjs[i] = null;
132         
133         if (ts==null || !ts.isValid())
134         continue;
135         
136         long maxInactiveInterval = ts.getMaxInactiveInterval();
137         if( log.isTraceEnabled() ) log.trace( "TS: " + maxInactiveInterval + " " +
138                 ts.getLastAccessedTime());
139         if (maxInactiveInterval < 0)
140         continue;
141         
142         long timeIdle = timeNow - ts.getThisAccessedTime();
143         
144         if (timeIdle >= maxInactiveInterval) {
145         if( expireCallback != null ) {
146             if( log.isDebugEnabled() )
147             log.debug( ts + " " + timeIdle + " " +
148                    maxInactiveInterval );
149             expireCallback.expired( ts );
150         }
151         }
152     }
153     }
154
155 }
156
Popular Tags