|
|
|
|
|
by edgeztv
6141 days ago
|
|
My solution for multithreaded testing in Java. Been using this code for a couple of years. Can easily be generalized for any asynchronous task. The main concept is using a shared barrier construct. /**
* Executes the task the given number of times in the given number of threads
* @return All the unchecked exceptions thrown by the task during execution, or
* an empty collection; never null.
*/
public Collection<Throwable> run(Runnable task, int nThreads, final int iterationsPerThread) throws BrokenBarrierException, InterruptedException {
// each thread will await upon the start barrier, then run the task, then await at the finish barrier (where the main thread will be waiting)
final CyclicBarrier startBarrier = new CyclicBarrier(nThreads);
final CyclicBarrier finishBarrier = new CyclicBarrier(nThreads + 1); // +1 for the main thread
// exceptions raised by threads will be logged and returned
final Collection<Throwable> exceptions = new ConcurrentLinkedQueue<Throwable>();
for (int i = 0; i < nThreads; i++) {
new Thread("Thread " + i) {
public void run() {
awaitOnBarrier(startBarrier, 5);
try {
for (int j = 0; j < iterationsPerThread; j++) {
task.run();
}
}
catch (Throwable e) {
e.printStackTrace();
exceptions.add(e);
}
finally {
awaitOnBarrier(finishBarrier, 60);
}
}
}.start();
}
finishBarrier.await();
return exceptions;
}
/** Calls barrier.await and supresses all its checked exceptions */
private void awaitOnBarrier(CyclicBarrier barrier, int timeoutSeconds) {
try {
barrier.await(timeoutSeconds, TimeUnit.SECONDS);
}
catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
catch (BrokenBarrierException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
catch (TimeoutException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
|
|