Source for org.jfree.report.util.Worker

   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: Worker.java 2725 2007-04-01 18:49:29Z taqua $
  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 worker implementation. The worker executes a assigned workload and then sleeps
  36:  * until another workload is set or the worker is killed.
  37:  *
  38:  * @author Thomas Morgner
  39:  */
  40: public final class Worker extends Thread
  41: {
  42:   /**
  43:    * the worker's task.
  44:    */
  45:   private Runnable workload;
  46: 
  47:   /**
  48:    * a flag whether the worker should exit after the processing.
  49:    */
  50:   private volatile boolean finish;
  51: 
  52:   /**
  53:    * The worker pool, to which this worker is assigned. May be null.
  54:    */
  55:   private WorkerPool workerPool;
  56: 
  57:   /**
  58:    * Creates a new worker.
  59:    *
  60:    * @param sleeptime the time this worker sleeps until he checks for new work.
  61:    */
  62:   public Worker ()
  63:   {
  64:     this.setDaemon(true);
  65:     start();
  66:   }
  67: 
  68:   /**
  69:    * Set the next workload for this worker.
  70:    *
  71:    * @param r the next workload for the worker.
  72:    * @throws IllegalStateException if the worker is not idle.
  73:    */
  74:   public void setWorkload (final Runnable r)
  75:   {
  76:     if (workload != null)
  77:     {
  78:       throw new IllegalStateException("This worker is not idle.");
  79:     }
  80:     //Log.debug("Workload set...");
  81:     synchronized (this)
  82:     {
  83:       workload = r;
  84:       //Log.debug("Workload assigned: Notified " + getName());
  85:       this.notifyAll();
  86:     }
  87:   }
  88: 
  89:   /**
  90:    * Returns the workload object.
  91:    *
  92:    * @return the runnable executed by this worker thread.
  93:    */
  94:   public synchronized Runnable getWorkload()
  95:   {
  96:     return workload;
  97:   }
  98: 
  99:   /**
 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: }