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