Frames | No Frames |
1: /** 2: * ======================================== 3: * JFreeReport : a free Java report library 4: * ======================================== 5: * 6: * Project Info: http://reporting.pentaho.org/ 7: * 8: * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors. 9: * 10: * This library is free software; you can redistribute it and/or modify it under the terms 11: * of the GNU Lesser General Public License as published by the Free Software Foundation; 12: * either version 2.1 of the License, or (at your option) any later version. 13: * 14: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 15: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16: * See the GNU Lesser General Public License for more details. 17: * 18: * You should have received a copy of the GNU Lesser General Public License along with this 19: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20: * Boston, MA 02111-1307, USA. 21: * 22: * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 23: * in the United States and other countries.] 24: * 25: * ------------ 26: * $Id: WorkerPool.java 3525 2007-10-16 11:43:48Z tmorgner $ 27: * ------------ 28: * (C) Copyright 2000-2005, by Object Refinery Limited. 29: * (C) Copyright 2005-2007, by Pentaho Corporation. 30: */ 31: 32: package org.jfree.report.util; 33: 34: /** 35: * A simple static workpool. Worker threads are created when necessary. 36: * 37: * @author Thomas Morgner 38: */ 39: public class WorkerPool 40: { 41: /** 42: * The worker array. 43: */ 44: private Worker[] workers; 45: /** 46: * A flag indicating whether idle workers are available. 47: */ 48: private boolean workersAvailable; 49: /** 50: * the name prefix for all workers of this pool. 51: */ 52: private String namePrefix; 53: 54: /** 55: * Creates a new worker pool with the default size of 10 workers and the default name. 56: */ 57: public WorkerPool () 58: { 59: this(10); 60: } 61: 62: /** 63: * Creates a new workerpool with the given number of workers and the default name. 64: * 65: * @param size the maximum number of workers available. 66: */ 67: public WorkerPool (final int size) 68: { 69: this(size, "WorkerPool-worker"); 70: } 71: 72: /** 73: * Creates a new worker pool for the given number of workers and with the given name 74: * prefix. 75: * 76: * @param size the size of the worker pool. 77: * @param namePrefix the name prefix for all created workers. 78: */ 79: public WorkerPool (final int size, final String namePrefix) 80: { 81: if (size <= 0) 82: { 83: throw new IllegalArgumentException("Size must be > 0"); 84: } 85: workers = new Worker[size]; 86: workersAvailable = true; 87: this.namePrefix = namePrefix; 88: } 89: 90: /** 91: * Checks, whether workers are available. 92: * 93: * @return true, if at least one worker is idle, false otherwise. 94: */ 95: public synchronized boolean isWorkerAvailable () 96: { 97: return workersAvailable; 98: } 99: 100: /** 101: * Updates the workersAvailable flag after a worker was assigned. 102: */ 103: private void updateWorkersAvailable () 104: { 105: for (int i = 0; i < workers.length; i++) 106: { 107: if (workers[i] == null) 108: { 109: workersAvailable = true; 110: return; 111: } 112: if (workers[i].isAvailable() == true) 113: { 114: workersAvailable = true; 115: return; 116: } 117: } 118: workersAvailable = false; 119: } 120: 121: /** 122: * Waits until a worker will be available. 123: */ 124: private synchronized void waitForWorkerAvailable () 125: { 126: while (isWorkerAvailable() == false) 127: { 128: try 129: { 130: // remove lock 131: this.wait(5000); 132: } 133: catch (InterruptedException ie) 134: { 135: // ignored 136: } 137: } 138: } 139: 140: /** 141: * Returns a workerhandle for the given workload. This method will wait until an idle 142: * worker is found. 143: * 144: * @param r the workload for the worker 145: * @return a handle to the worker. 146: */ 147: public synchronized WorkerHandle getWorkerForWorkload (final Runnable r) 148: { 149: waitForWorkerAvailable(); 150: 151: int emptySlot = -1; 152: for (int i = 0; i < workers.length; i++) 153: { 154: if (workers[i] == null) 155: { 156: // in the first run, try to avoid to create new threads... 157: // reuse the already available threads 158: if (emptySlot == -1) 159: { 160: emptySlot = i; 161: } 162: continue; 163: } 164: if (workers[i].isAvailable() == true) 165: { 166: workers[i].setWorkload(r); 167: updateWorkersAvailable(); 168: return new WorkerHandle(workers[i]); 169: } 170: } 171: if (emptySlot != -1) 172: { 173: workers[emptySlot] = new Worker(); 174: workers[emptySlot].setName(namePrefix + "-" + emptySlot); 175: workers[emptySlot].setWorkerPool(this); 176: workers[emptySlot].setWorkload(r); 177: updateWorkersAvailable(); 178: return new WorkerHandle(workers[emptySlot]); 179: } 180: throw new IllegalStateException 181: ("At this point, a worker should already have been assigned."); 182: } 183: 184: /** 185: * Marks the given worker as finished. The worker will be removed from the list of the 186: * available workers. 187: * 188: * @param worker the worker which was finished. 189: */ 190: public void workerFinished (final Worker worker) 191: { 192: if (worker.isFinish() == false) 193: { 194: throw new IllegalArgumentException("This worker is not in the finish state."); 195: } 196: for (int i = 0; i < workers.length; i++) 197: { 198: if (workers[i] == worker) 199: { 200: synchronized (this) 201: { 202: workers[i] = null; 203: workersAvailable = true; 204: this.notifyAll(); 205: } 206: return; 207: } 208: } 209: } 210: 211: /** 212: * Marks the given worker as available. 213: * 214: * @param worker the worker which was available. 215: */ 216: public synchronized void workerAvailable (final Worker worker) 217: { 218: for (int i = 0; i < workers.length; i++) 219: { 220: if (workers[i] == worker) 221: { 222: synchronized (this) 223: { 224: workersAvailable = true; 225: this.notifyAll(); 226: } 227: return; 228: } 229: } 230: } 231: 232: /** 233: * Finishes all worker of this pool. 234: */ 235: public void finishAll () 236: { 237: for (int i = 0; i < workers.length; i++) 238: { 239: if (workers[i] != null) 240: { 241: workers[i].finish(); 242: } 243: } 244: } 245: }