package com.constellio.sdk.tests.concurrent; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; public class OngoingConcurrentExecution { private int numberOfThreads; private ConcurrentJob job; public OngoingConcurrentExecution(ConcurrentJob job) { this.job = job; } public OngoingConcurrentExecution withThreads(int numberOfThreads) { this.numberOfThreads = numberOfThreads; return this; } public ConcurrentExecutionResults untilAllWorkerHasFinished() { final AtomicInteger nbInvokations = new AtomicInteger(); List<Thread> threads = new ArrayList<Thread>(); for (int i = 0; i < numberOfThreads; i++) { final int worker = i; threads.add(new Thread() { @Override public void run() { nbInvokations.incrementAndGet(); Map<String, Object> context = job.setupWorkerContext(worker); try { job.run(context, worker); } catch (Exception e) { throw new RuntimeException(e); } } }); } return runUntilFinished(threads, nbInvokations); } public ConcurrentExecutionResults untilTotalInvokationOf(final int totalInvokation) { final AtomicInteger nbInvokations = new AtomicInteger(); List<Thread> threads = new ArrayList<Thread>(); for (int i = 0; i < numberOfThreads; i++) { final int worker = i; threads.add(new Thread() { @Override public void run() { Map<String, Object> context = job.setupWorkerContext(worker); boolean alive = true; while (alive) { synchronized (OngoingConcurrentExecution.class) { if (nbInvokations.get() >= totalInvokation) { alive = false; } else { nbInvokations.incrementAndGet(); } } if (alive) { try { job.run(context, worker); } catch (Exception e) { throw new RuntimeException(e); } } } } }); } return runUntilFinished(threads, nbInvokations); } private ConcurrentExecutionResults runUntilFinished(List<Thread> threads, AtomicInteger nbInvokations) { long start = new Date().getTime(); for (Thread thread : threads) { thread.start(); } for (Thread thread : threads) { try { thread.join(); } catch (InterruptedException e) { throw new RuntimeException(e); } } long end = new Date().getTime(); return new ConcurrentExecutionResults(nbInvokations.get(), end - start); } }