1 /**********************************************************************
2 * ThreadPoolResizer.java
3 * created on 01.03.2005 by netseeker
4 * $Id: ThreadPoolResizer.java,v 1.5 2006/11/05 16:34:39 netseeker Exp $
5 * $Log: ThreadPoolResizer.java,v $
6 * Revision 1.5 2006/11/05 16:34:39 netseeker
7 * Code cleanup, added support of JDK 1.5 thread pools
8 *
9 * Revision 1.4 2006/08/10 18:57:06 netseeker
10 * *** empty log message ***
11 *
12 * Revision 1.3 2006/08/10 18:36:04 netseeker
13 * added abstraction of ThreadPools and an Executor based implementation for Java >= 1.5
14 *
15 * Revision 1.2 2006/08/09 20:13:54 netseeker
16 * *** empty log message ***
17 *
18 * Revision 1.1 2006/07/27 20:35:16 netseeker
19 * *** empty log message ***
20 *
21 *
22 * ====================================================================
23 *
24 * Copyright 2005-2006 netseeker aka Michael Manske
25 *
26 * Licensed under the Apache License, Version 2.0 (the "License");
27 * you may not use this file except in compliance with the License.
28 * You may obtain a copy of the License at
29 *
30 * http://www.apache.org/licenses/LICENSE-2.0
31 *
32 * Unless required by applicable law or agreed to in writing, software
33 * distributed under the License is distributed on an "AS IS" BASIS,
34 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35 * See the License for the specific language governing permissions and
36 * limitations under the License.
37 * ====================================================================
38 *
39 * This file is part of the ejoe framework.
40 * For more information on the author, please see
41 * <http://www.manskes.de/>.
42 *
43 *********************************************************************/
44 package de.netseeker.ejoe.concurrent;
45
46 import java.util.Timer;
47 import java.util.TimerTask;
48
49 /***
50 * A controller thread which monitors a ThreadService and ensures that the limit of worker threads within the
51 * ThreadService will be adjusted according to the workload.
52 *
53 * @author netseeker
54 * @since 0.3.9.1
55 */
56 public final class ThreadPoolResizer extends TimerTask
57 {
58 private ThreadService pool;
59
60 private int shrinkSize;
61
62 private long millisBeforeShrink = -1;
63
64 private long lastCheck = -1;
65
66 private int maxPoolSize;
67
68 /***
69 * Creates a new instance of ThreadPoolResizer, which can be scheduled via using a {@link Timer} and will monitor
70 * and eventually resize the given {@link ThreadService} up to the given limit of workers by checking the workload
71 * of the pool. If the workload is very high in all checks during the given period (millisBeforeShrink) the amount
72 * of workers in the monitored {@link ThreadService} will be increased to a calculated size between 1 and the given
73 * limit of workers. If the workload is too low the amount of workers will get reduced.
74 *
75 * @param pool a {@link ThreadService} to monitor
76 * @param maxPoolSize the limit of worker threads for the {@link ThreadService}
77 * @param millisBeforeShrink the period before the {@link ThreadService} will get resized
78 */
79 public ThreadPoolResizer(ThreadService pool, int maxPoolSize, long millisBeforeShrink)
80 {
81 super();
82 this.pool = pool;
83 this.maxPoolSize = maxPoolSize;
84 this.millisBeforeShrink = millisBeforeShrink;
85 }
86
87
88
89
90
91
92 public void run()
93 {
94 long now = System.currentTimeMillis();
95 if ( this.lastCheck == -1 ) this.lastCheck = now;
96
97 int current = pool.getCurrentPoolsize();
98 int active = pool.getActiveWorkerCount();
99
100 boolean shrinkPossible = (current - active) > 0;
101
102 if ( shrinkPossible )
103 {
104 if ( this.shrinkSize == 0 )
105 this.shrinkSize = (active > 0) ? active : 1;
106 else
107 this.shrinkSize = (int) Math.floor( (this.shrinkSize + active) / 2 );
108
109 if ( (now - this.lastCheck) >= this.millisBeforeShrink )
110 {
111 if ( this.shrinkSize > this.maxPoolSize )
112 {
113 this.shrinkSize = this.maxPoolSize;
114 }
115
116 pool.resize( this.shrinkSize );
117 }
118 }
119 else
120 this.shrinkSize = 0;
121
122 lastCheck = now;
123 }
124 }