KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > nava > informa > utils > toolkit > WorkerThread


1 //
2
// Informa -- RSS Library for Java
3
// Copyright (c) 2002 by Niko Schmuck
4
//
5
// Niko Schmuck
6
// http://sourceforge.net/projects/informa
7
// mailto:niko_schmuck@users.sourceforge.net
8
//
9
// This library is free software.
10
//
11
// You may redistribute it and/or modify it under the terms of the GNU
12
// Lesser General Public License as published by the Free Software Foundation.
13
//
14
// Version 2.1 of the license should be included with this distribution in
15
// the file LICENSE. If the license is not included with this distribution,
16
// you may find a copy at the FSF web site at 'www.gnu.org' or 'www.fsf.org',
17
// or you may write to the Free Software Foundation, 675 Mass Ave, Cambridge,
18
// MA 02139 USA.
19
//
20
// This library is distributed in the hope that it will be useful,
21
// but WITHOUT ANY WARRANTY; without even the implied waranty of
22
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23
// Lesser General Public License for more details.
24
//
25
// $Id: WorkerThread.java,v 1.1 2004/08/23 14:39:26 spyromus Exp $
26
//
27

28 package de.nava.informa.utils.toolkit;
29
30 /**
31  * Abstract worker thread which is driven by <code>WorkersManager</code>. Worker thread runs
32  * until <code>terminate</code> property is set to true. All of the threads are run in
33  * daemon mode and do not prevent application from sudden quit.
34  * <p>
35  * In order to do something useful with channel this class should be extended with implementation
36  * of <code>process()</code> method. This method is invoked each time the thread receives new
37  * processing task. Current class takes care of getting new tasks, marking busy state and
38  * other necessary tasks.</p>
39  * <p>
40  * After the task is finished worker checks <code>JobSourceIF</code> object (if specified)
41  * to get new assignments and it there's no job goes to sleep for a <code>IDLE_SLEEP_TIME</code>
42  * milliseconds. When manager finds new task it immediately awakens the thread. If the thread
43  * doesn't receive new assignments for an <code>IDLE_SLEEP_TIME</code> it checks the
44  * <code>JobSourceIF</code> object again by itself to find new task. This is done for greater
45  * safety reasons to avoid situations when the queue is full of tasks and workers are in endless
46  * sleep.
47  *
48  * @author Aleksey Gureev (spyromus@noizeramp.com)
49  */

50 public abstract class WorkerThread extends Thread JavaDoc {
51
52   /** Time to sleep between checks for new jobs (if no one awaken the thread). */
53   private static final int IDLE_SLEEP_TIME = 20000;
54
55   private boolean busy = false;
56   private boolean terminate = false;
57
58   private JobSourceIF jobSource;
59   private ChannelRecord channelRecord;
60
61   /**
62    * Creates named worker thread.
63    *
64    * @param name name of the thread.
65    */

66   public WorkerThread(String JavaDoc name) {
67     super(name);
68   }
69
70   /**
71    * Sets new job source object. It will be used to get new tasks on completion.
72    *
73    * @param source source of new tasks.
74    */

75   public final void setJobSource(JobSourceIF source) {
76     this.jobSource = source;
77   }
78
79   /**
80    * Marks this thread for termination on job completion.
81    */

82   public final void terminate() {
83     this.terminate = true;
84     synchronized (this) {
85       notifyAll();
86     }
87   }
88
89   /**
90    * Returns business state of thread.
91    *
92    * @return TRUE if thread is currently processing something.
93    */

94   public final boolean isBusy() {
95     return busy;
96   }
97
98   /**
99    * Sets job, which requre immediate processing, and awakes the thread.
100    *
101    * @param rec job record.
102    * @return TRUE if job accepted.
103    */

104   public final synchronized boolean startJob(ChannelRecord rec) {
105     boolean accepted = false;
106
107     if (!this.busy) {
108       synchronized (this) {
109         this.busy = true;
110         channelRecord = rec;
111         notifyAll();
112       }
113       accepted = true;
114     }
115
116     return accepted;
117   }
118
119   /**
120    * Returns channel which is currently in processing.
121    *
122    * @return channel.
123    */

124   public final ChannelRecord getChannelInProcess() {
125     return channelRecord;
126   }
127
128   /**
129    * If this thread was constructed using a separate
130    * <code>Runnable</code> run object, then that
131    * <code>Runnable</code> object's <code>run</code> method is called;
132    * otherwise, this method does nothing and returns.
133    * <p/>
134    * Subclasses of <code>Thread</code> should override this method.
135    *
136    * @see Thread#start()
137    * @see Thread#stop()
138    * @see Thread#Thread(ThreadGroup, Runnable, String)
139    * @see Runnable#run()
140    */

141   public final void run() {
142     // Loop until termination.
143
while (!terminate) {
144       try {
145         // This one waits for itself, which is endless wait by itself.
146
// I use it to wait for interruption.
147
if (!terminate) {
148           synchronized (this) {
149             this.wait(IDLE_SLEEP_TIME);
150           }
151         }
152       } catch (InterruptedException JavaDoc e) {
153         // Awaken by someone
154
}
155
156       doJob();
157     }
158   }
159
160   /**
161    * Performs single unit of work.
162    */

163   private void doJob() {
164     // While there is something to do left then continue.
165
while (channelRecord != null) {
166       processRecord(channelRecord);
167
168       // Ask for next job if we don't need to terminate execution.
169
channelRecord = null;
170       if (!terminate && jobSource != null) {
171         channelRecord = jobSource.getNextJob();
172       }
173     }
174
175     // If there's nothing to do then finish.
176
synchronized (this) {
177       busy = (channelRecord != null);
178     }
179   }
180
181   /**
182    * Processes record.
183    *
184    * @param record record to process.
185    */

186   protected abstract void processRecord(ChannelRecord record);
187 }
188
Popular Tags