View Javadoc

1   package com.explosion.utilities.process.threads;
2   
3   /*
4    * =============================================================================
5    * 
6    * Copyright 2004 Stephen Cowx
7    * 
8    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
9    * use this file except in compliance with the License. You may obtain a copy of
10   * the License at
11   * 
12   * http://www.apache.org/licenses/LICENSE-2.0
13   * 
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
19   * 
20   * =============================================================================
21   */
22  
23  import java.util.Date;
24  
25  import org.apache.log4j.LogManager;
26  import org.apache.log4j.Logger;
27  
28  import com.explosion.utilities.process.ProcessMonitor;
29  
30  public class UnitisedProcessThread implements ProcessThread
31  {
32  
33      private static Logger log = LogManager.getLogger(UnitisedProcessThread.class);
34  
35      /* Thread controls */
36      private int interval = 10;
37  
38      private int priority = Thread.NORM_PRIORITY;
39  
40      private Thread executionThread;
41  
42      private Thread thisThread;
43  
44      /* Control elements */
45      private boolean finalised = false;
46  
47      private com.explosion.utilities.process.threads.UnitisedProcess process;
48  
49      private Date startTime = null;
50  
51      private Date endTime = null;
52  
53      private int status = THREAD_NOT_YET_STARTED;
54  
55      private boolean wasKilled = false;
56  
57      private boolean isUserProcess = false;
58      
59      /***
60       * For an explanation on implementing safely stoppable and suspendable
61       * threads please see
62       * 
63       * @see http://java.sun.com/products/jdk/1.2/docs/guide/misc/threadPrimitiveDeprecation.html
64       */
65      public void run()
66      {
67          try
68          {
69              thisThread = Thread.currentThread();
70              
71              ProcessMonitor.registerProcess(this, isUserProcess);
72              
73              checkSuspended();
74  
75              process.initialiseProcessing();
76  
77              checkSuspended();
78  
79              /* Perform processing */
80              stop: while (executionThread == thisThread && process.getPercentComplete() < 100)
81              {
82                  checkSuspended();
83                  if (status == THREAD_STOPPED) break;
84  
85                  /* Perform a ProcessingUnit */
86                  process.beginProcessUnit();
87  
88                  checkSuspended();
89                  if (status == THREAD_STOPPED) break;
90  
91                  while (!process.processUnitComplete())
92                  {
93                      checkSuspended();
94                      if (status == THREAD_STOPPED) continue stop;
95  
96                      process.processUnit();
97  
98                      checkSuspended();
99                      if (status == THREAD_STOPPED) continue stop;
100                 }
101 
102                 process.endProcessUnit();
103                 checkSuspended();
104                 if (status == THREAD_STOPPED) break;
105 
106                 /* Sleep for required interval */
107                 try
108                 {
109                     if (interval > 0) Thread.sleep(interval);
110                 } catch (InterruptedException e)
111                 {}
112             }
113 
114             process.finaliseProcessing();
115         } catch (Exception ex)
116         {
117             process.finaliseProcessing(ex);
118         }
119 
120         /* Set the status to completed */
121         status = THREAD_COMPLETED;
122     }
123 
124     /***
125      * Performs suspend logic if the thread has been suspended
126      */
127     public void checkSuspended()
128     {
129         /* Suspend if required */
130         if (status == THREAD_SUSPENDED)
131         {
132             synchronized (this)
133             {
134                 while (status == THREAD_SUSPENDED && executionThread == thisThread)
135                 {
136                     try
137                     {
138                         wait();
139                     } catch (InterruptedException e)
140                     {}
141                 }
142             }
143         }
144     }
145 
146     /***
147      * Starts the job.
148      */
149     public void start()
150     {
151         status = THREAD_STARTED;
152         startTime = new Date();
153 
154         executionThread = new Thread(this);
155         executionThread.setPriority(priority);
156         executionThread.start();
157     }
158 
159     /***
160      * Stop the job
161      */
162     public synchronized void stop()
163     {
164         executionThread = null;
165         notify();
166         endTime = new Date();
167         status = THREAD_STOPPED;
168     }
169 
170     /***
171      * Ssuspend the job.
172      */
173     public synchronized void suspend()
174     {
175         status = THREAD_SUSPENDED;
176         log.debug("suspended");
177     }
178 
179     /***
180      * Restart the job.
181      */
182     public synchronized void resume()
183     {
184         status = THREAD_STARTED;
185         notifyAll();
186         log.debug("resumed");
187     }
188 
189     /***
190      * This method allows the user to set the Thread priority of this
191      * controllable object. Possible priorities are: a) Thread.NORM_PRIORITY, b)
192      * Thread.MAX_PRIORITY c) Thread.MIN_PRIORITY The default priority is
193      * Thread.NORM_PRIORITY.
194      */
195     public void setPriority(int priority)
196     {
197         this.priority = priority;
198     }
199 
200     /***
201      * This method allows the user to set the interval between each thread loop.
202      * Default is 10 (0.001 seconds);
203      */
204     public void setInterval(int interval)
205     {
206         this.interval = interval;
207     }
208 
209     /***
210      * Set the UnitisedProcess for this UnitisedProcess
211      */
212     public void setProcess(com.explosion.utilities.process.threads.Process process)
213     {
214         this.process = (UnitisedProcess) process;
215     }
216 
217     /***
218      * Gets the process for this UnitisedProcess
219      */
220     public com.explosion.utilities.process.threads.Process getProcess()
221     {
222         return process;
223     }
224 
225     /***
226      * This method returns the actual thread object upon which this Runnable
227      * object is operating.
228      */
229     public Thread getRunThread()
230     {
231         return thisThread;
232     }
233 
234     /***
235      * This method returns status of the thread
236      */
237     public int getStatus()
238     {
239         return status;
240     }
241 
242     /***
243      * Kills the job
244      */
245     public void kill()
246     {
247         stop();
248         wasKilled = true;
249     }
250 
251     /***
252      * Returns whether or not the job was killed
253      */
254     public boolean wasKilled()
255     {
256         return wasKilled;
257     }
258 
259     /***
260      * Returns a boolean value indicating whther this is a userThread or not
261      * @return
262      */
263     public boolean isUserThread()
264     {
265         return this.isUserProcess;
266     }
267     
268     /***
269      * Sets whtether or not this is a user process.  True means that it is
270      * @param truth
271      */
272     public void setUserThread(boolean truth)
273     {
274         this.isUserProcess = true;
275     }
276 
277 }
278