01: /*
02: * Copyright (C) The MX4J Contributors.
03: * All rights reserved.
04: *
05: * This software is distributed under the terms of the MX4J License version 1.0.
06: * See the terms of the MX4J License in the documentation provided with this software.
07: */
08:
09: package test;
10:
11: import java.io.PrintStream;
12: import java.io.PrintWriter;
13: import java.util.ArrayList;
14: import java.util.List;
15:
16: /**
17: * @version $Revision: 1.3 $
18: */
19: public class MultiThreadTestRunner {
20: public abstract static class Test {
21: private List throwables = new ArrayList();
22:
23: public abstract void test() throws Exception;
24:
25: private synchronized void addThrowable(Throwable x) {
26: throwables.add(x);
27: }
28:
29: private synchronized Throwable[] getThrowables() {
30: return (Throwable[]) throwables
31: .toArray(new Throwable[throwables.size()]);
32: }
33: }
34:
35: private class MultiThrowable extends Exception {
36: private final Throwable[] throwables;
37:
38: public MultiThrowable(Throwable[] throwables) {
39: this .throwables = throwables;
40: }
41:
42: public void printStackTrace(PrintStream stream) {
43: synchronized (stream) {
44: stream.println(this );
45: for (int i = 0; i < throwables.length; ++i)
46: throwables[i].printStackTrace(stream);
47: }
48: }
49:
50: public void printStackTrace(PrintWriter writer) {
51: synchronized (writer) {
52: writer.println(this );
53: for (int i = 0; i < throwables.length; ++i)
54: throwables[i].printStackTrace(writer);
55: }
56: }
57: }
58:
59: private final int threads;
60: private final int iterations;
61:
62: public MultiThreadTestRunner(int threads, int iterations) {
63: this .threads = threads;
64: this .iterations = iterations;
65: }
66:
67: public void run(final Test test) throws Exception {
68: Thread[] runners = new Thread[threads];
69: for (int i = 0; i < threads; ++i) {
70: runners[i] = new Thread(new Runnable() {
71: public void run() {
72: for (int i = 0; i < iterations; ++i) {
73: try {
74: test.test();
75: } catch (Throwable x) {
76: test.addThrowable(x);
77: }
78: }
79: }
80: });
81: }
82:
83: for (int i = 0; i < threads; ++i)
84: runners[i].start();
85:
86: for (int i = 0; i < threads; ++i)
87: runners[i].join();
88:
89: Throwable[] failures = test.getThrowables();
90: if (failures != null && failures.length > 0)
91: throw new MultiThrowable(failures);
92: }
93: }
|