001 /** 002 * ======================================== 003 * JFreeReport : a free Java report library 004 * ======================================== 005 * 006 * Project Info: http://reporting.pentaho.org/ 007 * 008 * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors. 009 * 010 * This library is free software; you can redistribute it and/or modify it under the terms 011 * of the GNU Lesser General Public License as published by the Free Software Foundation; 012 * either version 2.1 of the License, or (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 015 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 016 * See the GNU Lesser General Public License for more details. 017 * 018 * You should have received a copy of the GNU Lesser General Public License along with this 019 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 020 * Boston, MA 02111-1307, USA. 021 * 022 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 023 * in the United States and other countries.] 024 * 025 * ------------ 026 * $Id: Worker.java 3048 2007-07-28 18:02:42Z tmorgner $ 027 * ------------ 028 * (C) Copyright 2000-2005, by Object Refinery Limited. 029 * (C) Copyright 2005-2007, by Pentaho Corporation. 030 */ 031 032 package org.jfree.report.util; 033 034 /** 035 * A simple worker implementation. The worker executes a assigned workload and then sleeps 036 * until another workload is set or the worker is killed. 037 * 038 * @author Thomas Morgner 039 */ 040 public final class Worker extends Thread 041 { 042 /** 043 * the worker's task. 044 */ 045 private Runnable workload; 046 047 /** 048 * a flag whether the worker should exit after the processing. 049 */ 050 private volatile boolean finish; 051 052 /** 053 * The worker pool, to which this worker is assigned. May be null. 054 */ 055 private WorkerPool workerPool; 056 057 /** 058 * Creates a new worker. 059 * 060 * @param sleeptime the time this worker sleeps until he checks for new work. 061 */ 062 public Worker () 063 { 064 this.setDaemon(true); 065 start(); 066 } 067 068 /** 069 * Set the next workload for this worker. 070 * 071 * @param r the next workload for the worker. 072 * @throws IllegalStateException if the worker is not idle. 073 */ 074 public void setWorkload (final Runnable r) 075 { 076 if (workload != null) 077 { 078 throw new IllegalStateException("This worker is not idle."); 079 } 080 //Log.debug("Workload set..."); 081 synchronized (this) 082 { 083 workload = r; 084 //Log.debug("Workload assigned: Notified " + getName()); 085 this.notifyAll(); 086 } 087 } 088 089 /** 090 * Returns the workload object. 091 * 092 * @return the runnable executed by this worker thread. 093 */ 094 public synchronized Runnable getWorkload() 095 { 096 return workload; 097 } 098 099 /** 100 * Kills the worker after he completed his work. Awakens the worker if he's sleeping, so 101 * that the worker dies without delay. 102 */ 103 public void finish () 104 { 105 finish = true; 106 // we are evil .. 107 try 108 { 109 this.interrupt(); 110 this.notifyAll(); 111 } 112 catch (SecurityException se) 113 { 114 // ignored 115 } 116 if (workerPool != null) 117 { 118 workerPool.workerFinished(this); 119 } 120 } 121 122 /** 123 * Checks, whether this worker has some work to do. 124 * 125 * @return true, if this worker has no more work and is currently sleeping. 126 */ 127 public boolean isAvailable () 128 { 129 return (workload == null); 130 } 131 132 /** 133 * If a workload is set, process it. After the workload is processed, this worker starts 134 * to sleep until a new workload is set for the worker or the worker got the finish() 135 * request. 136 */ 137 public synchronized void run () 138 { 139 while (!finish) 140 { 141 if (workload != null) 142 { 143 try 144 { 145 workload.run(); 146 } 147 catch (Exception e) 148 { 149 org.jfree.util.Log.error("Worker caught exception on run: ", e); 150 } 151 workload = null; 152 if (workerPool != null) 153 { 154 workerPool.workerAvailable(this); 155 } 156 } 157 158 synchronized (this) 159 { 160 try 161 { 162 this.wait(); 163 } 164 catch (InterruptedException ie) 165 { 166 // ignored 167 } 168 } 169 } 170 } 171 172 /** 173 * Checks whether this worker has received the signal to finish and die. 174 * 175 * @return true, if the worker should finish the work and end the thread. 176 */ 177 public boolean isFinish () 178 { 179 return finish; 180 } 181 182 /** 183 * Returns the worker's assigned pool. 184 * 185 * @return the worker pool (or null, if the worker is not assigned to a pool). 186 */ 187 public WorkerPool getWorkerPool () 188 { 189 return workerPool; 190 } 191 192 /** 193 * Defines the worker's assigned pool. 194 * 195 * @param workerPool the worker pool (or null, if the worker is not assigned to a 196 * pool). 197 */ 198 public void setWorkerPool (final WorkerPool workerPool) 199 { 200 this.workerPool = workerPool; 201 } 202 }