マルチスレッドのテスト
junitではマルチスレッドのコードをテストすることは困難であるため、Executor serviceフレームワークのような他の方法が必要である.最近、モニタリングクラスの出力状況にテストを書き、出力フォーマットが予想通りに一致するかどうかを簡単に走ります.ここではThreadPoolExecutor+CompletionServicesを借りました.すなわち、終了前にスレッドプールから最後の実行結果を得る必要がある.マルチスレッドテストモードは似ていると思います.忘れないでください.
public class MonitorHelperTest {
private Worker[] workers;
ExecutorService pool;
CompletionService<Boolean> completionPool;
List<Future<Boolean>> futures;
static int count = 100;
static int countPreThread = 1000;
private static class Worker implements Callable<Boolean> {
@Override
public Boolean call() throws Exception {
for (int i = 0; i < countPreThread; i++) {
Action action = Action.values()[i % Action.values().length];
doFoo(i, action);
}
return true;
}
private void doFoo(int i, Action action) {
long begin = MonitorHelper.addFetchAndGetNow(action, 1);
try {
foo(i);
MonitorHelper.addTime(action, begin);
MonitorHelper.addSuccess(action);
} catch (Exception e) {
MonitorHelper.addFailure(action);
}
}
}
@Before
public void before() {
pool = Executors.newFixedThreadPool(count, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "worker");
}
});
completionPool = new ExecutorCompletionService<Boolean>(pool);
futures = new ArrayList<Future<Boolean>>(count);
workers = new Worker[count];
for (int i = 0; i < count; i++) {
workers[i] = new Worker();
}
}
@Test
public void test() throws Exception {
for (Worker worker : workers) {
futures.add(completionPool.submit(worker));
}
for (int i = 0; i < count; i++) {
completionPool.take().get();
}
}
/**
* @throws Exception
*
*/
private static void foo(int i) throws Exception {
if (i % 3 == 0) {
TimeUnit.MILLISECONDS.sleep(50);
throw new Exception();
} else {
TimeUnit.MILLISECONDS.sleep(100);
}
}
}