1 19 package org.apache.excalibur.mpool.test; 20 21 import org.apache.avalon.framework.logger.AbstractLogEnabled; 22 import org.apache.avalon.framework.logger.Logger; 23 24 38 public class LatchedThreadGroup 39 extends AbstractLogEnabled 40 { 41 private Thread [] m_threads; 42 private Object m_semaphore = new Object (); 43 private int m_startedCount; 44 private boolean m_latched; 45 private int m_completedCount; 46 private Throwable m_exception; 47 48 51 54 public LatchedThreadGroup( Runnable [] runnables ) 55 { 56 int threadCount = runnables.length; 57 m_threads = new Thread [ threadCount ]; 58 for( int i = 0; i < threadCount; i++ ) 59 { 60 m_threads[ i ] = new Runner( runnables[ i ], "Latched_Thread_" + i ); 61 } 62 } 63 64 67 public LatchedThreadGroup( Runnable runnable, int threadCount ) 68 { 69 m_threads = new Thread [ threadCount ]; 70 for( int i = 0; i < threadCount; i++ ) 71 { 72 m_threads[ i ] = new Runner( runnable, "Latched_Thread_" + i ); 73 } 74 } 75 76 79 protected void resetMemory() 80 { 81 System.gc(); 82 System.gc(); 83 84 try 86 { 87 Thread.sleep( 50 ); 88 } 89 catch( InterruptedException e ) 90 { 91 } 92 Runtime runtime = Runtime.getRuntime(); 93 getLogger().debug( "Memory: " + ( runtime.totalMemory() - runtime.freeMemory() ) ); 94 } 95 96 102 public long go() 103 throws Exception ![JavaDoc](../../../../../../cmn/javadoc.gif) 104 { 105 int threadCount = m_threads.length; 109 for( int i = 0; i < threadCount; i++ ) 110 { 111 m_threads[ i ].start(); 112 } 113 114 synchronized( m_semaphore ) 116 { 117 while( m_startedCount < threadCount ) 118 { 119 m_semaphore.wait(); 120 } 121 122 resetMemory(); 124 125 m_latched = true; 127 getLogger().debug( "Main thread released the test thread latch." ); 128 m_semaphore.notifyAll(); 129 } 130 long startTime = System.currentTimeMillis(); 132 133 synchronized( m_semaphore ) 135 { 136 getLogger().debug( "Waiting for test threads to all complete." ); 137 while( m_completedCount < threadCount ) 138 { 139 try 140 { 141 m_semaphore.wait(); 142 } 143 catch( InterruptedException e ) 144 { 145 } 146 } 147 } 148 final long duration = System.currentTimeMillis() - startTime; 149 getLogger().debug( "All test threads completed." ); 150 151 if( m_exception != null ) 152 { 153 throw new CascadingAssertionFailedError( "Exception in test thread.", m_exception ); 154 } 155 return duration; 156 } 157 158 163 private Logger getInnerLogger() 164 { 165 return getLogger(); 166 } 167 168 171 private class Runner extends Thread ![JavaDoc](../../../../../../cmn/javadoc.gif) 172 { 173 private Runnable m_runnable; 174 175 protected Runner( Runnable runnable, String name ) 176 { 177 super( name ); 178 m_runnable = runnable; 179 } 180 181 public void run() 182 { 183 try 184 { 185 synchronized( m_semaphore ) 187 { 188 m_startedCount++; 189 getInnerLogger().debug( "Started " + m_startedCount + " test threads." ); 190 if( m_startedCount >= m_threads.length ) 191 { 192 m_semaphore.notifyAll(); 193 } 194 while( !m_latched ) 195 { 196 try 197 { 198 m_semaphore.wait(); 199 } 200 catch( InterruptedException e ) 201 { 202 } 203 } 204 } 205 206 try 208 { 209 m_runnable.run(); 210 } 211 catch( Throwable t ) 212 { 213 synchronized( m_semaphore ) 214 { 215 getInnerLogger().error( "Error in " + Thread.currentThread().getName(), t ); 216 if( m_exception != null ) 217 { 218 m_exception = t; 219 } 220 } 221 } 222 } 223 finally 224 { 225 synchronized( m_semaphore ) 227 { 228 m_completedCount++; 229 getInnerLogger().debug( m_completedCount + " test threads completed." ); 230 m_semaphore.notifyAll(); 231 } 232 } 233 } 234 } 235 } 236 | Popular Tags |