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: */package org.jfree.report.util;
031:
032: /**
033: * A simple worker implementation. The worker executes a assigned workload and then sleeps
034: * until another workload is set or the worker is killed.
035: *
036: * @author Thomas Morgner
037: */
038: public final class Worker extends Thread {
039: /**
040: * the worker's task.
041: */
042: private Runnable workload;
043:
044: /**
045: * a flag whether the worker should exit after the processing.
046: */
047: private volatile boolean finish;
048:
049: /**
050: * The worker pool, to which this worker is assigned. May be null.
051: */
052: private WorkerPool workerPool;
053:
054: /**
055: * Creates a new worker.
056: *
057: * @param sleeptime the time this worker sleeps until he checks for new work.
058: */
059: public Worker() {
060: this .setDaemon(true);
061: start();
062: }
063:
064: /**
065: * Set the next workload for this worker.
066: *
067: * @param r the next workload for the worker.
068: * @throws IllegalStateException if the worker is not idle.
069: */
070: public void setWorkload(final Runnable r) {
071: if (workload != null) {
072: throw new IllegalStateException("This worker is not idle.");
073: }
074: //Log.debug("Workload set...");
075: synchronized (this ) {
076: workload = r;
077: //Log.debug("Workload assigned: Notified " + getName());
078: this .notifyAll();
079: }
080: }
081:
082: /**
083: * Returns the workload object.
084: *
085: * @return the runnable executed by this worker thread.
086: */
087: public synchronized Runnable getWorkload() {
088: return workload;
089: }
090:
091: /**
092: * Kills the worker after he completed his work. Awakens the worker if he's sleeping, so
093: * that the worker dies without delay.
094: */
095: public void finish() {
096: finish = true;
097: // we are evil ..
098: try {
099: this .interrupt();
100: this .notifyAll();
101: } catch (SecurityException se) {
102: // ignored
103: }
104: if (workerPool != null) {
105: workerPool.workerFinished(this );
106: }
107: }
108:
109: /**
110: * Checks, whether this worker has some work to do.
111: *
112: * @return true, if this worker has no more work and is currently sleeping.
113: */
114: public boolean isAvailable() {
115: return (workload == null);
116: }
117:
118: /**
119: * If a workload is set, process it. After the workload is processed, this worker starts
120: * to sleep until a new workload is set for the worker or the worker got the finish()
121: * request.
122: */
123: public synchronized void run() {
124: while (!finish) {
125: if (workload != null) {
126: try {
127: workload.run();
128: } catch (Exception e) {
129: org.jfree.util.Log.error(
130: "Worker caught exception on run: ", e);
131: }
132: workload = null;
133: if (workerPool != null) {
134: workerPool.workerAvailable(this );
135: }
136: }
137:
138: synchronized (this ) {
139: try {
140: this .wait();
141: } catch (InterruptedException ie) {
142: // ignored
143: }
144: }
145: }
146: }
147:
148: /**
149: * Checks whether this worker has received the signal to finish and die.
150: *
151: * @return true, if the worker should finish the work and end the thread.
152: */
153: public boolean isFinish() {
154: return finish;
155: }
156:
157: /**
158: * Returns the worker's assigned pool.
159: *
160: * @return the worker pool (or null, if the worker is not assigned to a pool).
161: */
162: public WorkerPool getWorkerPool() {
163: return workerPool;
164: }
165:
166: /**
167: * Defines the worker's assigned pool.
168: *
169: * @param workerPool the worker pool (or null, if the worker is not assigned to a
170: * pool).
171: */
172: public void setWorkerPool(final WorkerPool workerPool) {
173: this.workerPool = workerPool;
174: }
175: }
|