1 17 package org.apache.excalibur.thread.impl; 18 19 import org.apache.excalibur.thread.Executable; 20 import org.apache.excalibur.thread.ThreadControl; 21 22 27 public class WorkerThread 28 extends Thread 29 { 30 34 private static final boolean ENABLE_DEBUG = false; 35 36 40 private static final boolean ENABLE_DETAIL_DEBUG = false; 41 42 45 private Executable m_work; 46 47 51 private DefaultThreadControl m_threadControl; 52 53 56 private boolean m_alive; 57 58 61 private boolean m_clearInterruptFlag; 62 63 66 private final AbstractThreadPool m_pool; 67 68 71 protected WorkerThread( final AbstractThreadPool pool, 72 final ThreadGroup group, 73 final String name ) 74 { 75 super( group, "" ); 76 if( null == name ) 77 { 78 throw new NullPointerException ( "name" ); 79 } 80 if( null == pool ) 81 { 82 throw new NullPointerException ( "pool" ); 83 } 84 85 setName( name ); 86 m_work = null; 87 m_alive = true; 88 m_clearInterruptFlag = false; 89 m_pool = pool; 90 91 setDaemon( false ); 92 } 93 94 97 public final synchronized void run() 98 { 99 debug( "starting." ); 100 try 101 { 102 while( m_alive ) 103 { 104 waitForWork(); 105 if ( m_alive ) 106 { 107 detailDebug( "start with work: " + m_work ); 108 109 try 110 { 111 try 112 { 113 preExecute(); 114 115 m_work.execute(); 117 118 m_threadControl.finish( null ); 120 } 121 catch( final ThreadDeath threadDeath ) 122 { 123 debug( "thread has died." ); 124 m_threadControl.finish( threadDeath ); 125 126 throw threadDeath; 129 } 130 catch( final Throwable throwable ) 131 { 132 debug( "error caught", throwable ); 134 m_threadControl.finish( throwable ); 135 } 136 } 137 finally 138 { 139 detailDebug( "done with work: " + m_work ); 140 141 m_work = null; 142 m_threadControl = null; 143 144 if ( m_clearInterruptFlag ) 145 { 146 clearInterruptFlag(); 147 } 148 149 postExecute(); 150 } 151 152 183 184 188 notify(); 192 193 recycleThread(); 195 } 196 } 197 } 198 finally 199 { 200 debug( "stopped." ); 201 } 202 } 203 204 207 protected void recycleThread() 208 { 209 if ( !m_alive ) 210 { 211 throw new IllegalStateException ( "Attempted to recycle dead thread." ); 212 } 213 214 detailDebug( "recycle." ); 215 if ( m_clearInterruptFlag ) 216 { 217 clearInterruptFlag(); 218 } 219 m_pool.releaseWorker( this ); 220 } 221 222 226 protected void postExecute() 227 { 228 } 229 230 234 protected void preExecute() 235 { 236 clearInterruptFlag(); 237 } 240 241 248 public void clearInterruptFlag() 249 { 250 if (Thread.currentThread().equals(this)) 251 { 252 Thread.interrupted(); 253 m_clearInterruptFlag = false; 254 } 255 else 256 { 257 m_clearInterruptFlag = true; 258 } 259 } 260 261 269 public void dispose() 270 { 271 debug( "destroying." ); 272 273 m_alive = false; 274 275 synchronized(this) 277 { 278 this.notify(); 279 } 280 281 debug( "destroyed." ); 282 } 283 284 288 protected synchronized ThreadControl execute( final Executable work ) 289 { 290 m_work = work; 291 m_threadControl = new DefaultThreadControl( this ); 292 293 detailDebug( "notifying this worker of new work: " + work.toString() ); 294 notify(); 295 296 return m_threadControl; 297 } 298 299 304 protected void executeAndWait( final Executable work ) 305 { 306 execute( work ); 308 309 synchronized(this) 311 { 312 while( null != m_work ) 313 { 314 try 315 { 316 detailDebug( "waiting for work to complete." ); 317 wait(); 318 detailDebug( "notified." ); 319 } 320 catch( final InterruptedException ie ) 321 { 322 } 324 } 325 } 326 } 327 328 331 private void waitForWork() 332 { 333 synchronized(this) 334 { 335 while( m_alive && ( null == m_work ) ) 336 { 337 try 338 { 339 detailDebug( "waiting for work." ); 340 wait(); 341 detailDebug( "notified." ); 342 } 343 catch( final InterruptedException ie ) 344 { 345 } 347 } 348 } 349 } 350 351 360 protected void debug( final String message ) 361 { 362 if( ENABLE_DEBUG ) 363 { 364 System.out.println( getName() + ": " + message ); 365 } 366 } 367 368 378 protected void debug( final String message, final Throwable throwable ) 379 { 380 if( ENABLE_DEBUG ) 381 { 382 System.out.println( getName() + ": " + message + ": " + throwable ); 383 } 384 } 385 386 396 protected void detailDebug( final String message ) 397 { 398 if ( ENABLE_DETAIL_DEBUG ) 399 { 400 System.out.println( getName() + ": " + message ); 401 } 402 } 403 404 415 protected void detailDebug( final String message, final Throwable throwable ) 416 { 417 if ( ENABLE_DETAIL_DEBUG ) 418 { 419 System.out.println( getName() + ": " + message + ": " + throwable ); 420 } 421 } 422 } 423 | Popular Tags |