2626import java .util .Collection ;
2727import java .util .List ;
2828import java .util .Random ;
29+ import java .util .concurrent .CountDownLatch ;
2930import java .util .concurrent .ExecutionException ;
3031import java .util .concurrent .ExecutorService ;
3132import java .util .concurrent .Executors ;
3233import java .util .concurrent .Future ;
3334import java .util .concurrent .ScheduledExecutorService ;
34- import java .util .concurrent .SynchronousQueue ;
35- import java .util .concurrent .ThreadPoolExecutor ;
3635import java .util .concurrent .TimeUnit ;
3736import java .util .concurrent .TimeoutException ;
3837import java .util .function .Supplier ;
@@ -52,19 +51,21 @@ public class MulticastSet {
5251
5352 private ThreadingHandler threadingHandler = new DefaultThreadingHandler ();
5453
54+ private final CompletionHandler completionHandler ;
55+
5556 public MulticastSet (Stats stats , ConnectionFactory factory ,
56- MulticastParams params , List <String > uris ) {
57- this (stats , factory , params , "perftest" , uris );
57+ MulticastParams params , List <String > uris , CompletionHandler completionHandler ) {
58+ this (stats , factory , params , "perftest" , uris , completionHandler );
5859 }
5960
6061 public MulticastSet (Stats stats , ConnectionFactory factory ,
61- MulticastParams params , String testID , List <String > uris ) {
62+ MulticastParams params , String testID , List <String > uris , CompletionHandler completionHandler ) {
6263 this .stats = stats ;
6364 this .factory = factory ;
6465 this .params = params ;
6566 this .testID = testID ;
6667 this .uris = uris ;
67-
68+ this . completionHandler = completionHandler ;
6869 this .params .init ();
6970 }
7071
@@ -108,7 +109,7 @@ public void run(boolean announceStartup)
108109 if (announceStartup ) {
109110 System .out .println ("id: " + testID + ", starting consumer #" + i + ", channel #" + j );
110111 }
111- consumerRunnables [(i * params .getConsumerChannelCount ()) + j ] = params .createConsumer (conn , stats );
112+ consumerRunnables [(i * params .getConsumerChannelCount ()) + j ] = params .createConsumer (conn , stats , this . completionHandler );
112113 }
113114 }
114115
@@ -134,7 +135,7 @@ public void run(boolean announceStartup)
134135 System .out .println ("id: " + testID + ", starting producer #" + i + ", channel #" + j );
135136 }
136137 AgentState agentState = new AgentState ();
137- agentState .runnable = params .createProducer (conn , stats );
138+ agentState .runnable = params .createProducer (conn , stats , this . completionHandler );
138139 producerStates [(i * params .getProducerChannelCount ()) + j ] = agentState ;
139140 }
140141 }
@@ -154,9 +155,11 @@ public void run(boolean announceStartup)
154155 producerState .task = producersExecutorService .submit (producerState .runnable );
155156 }
156157
158+ this .completionHandler .waitForCompletion ();
159+
157160 int count = 1 ; // counting the threads
158161 for (int i = 0 ; i < producerStates .length ; i ++) {
159- producerStates [i ].task .get ( );
162+ producerStates [i ].task .cancel ( true );
160163 if (count % params .getProducerChannelCount () == 0 ) {
161164 // this is the end of a group of threads on the same connection,
162165 // closing the connection
@@ -251,4 +254,51 @@ private static class AgentState {
251254
252255 }
253256
257+ interface CompletionHandler {
258+
259+ void waitForCompletion () throws InterruptedException ;
260+
261+ void countDown ();
262+
263+ }
264+
265+ static class DefaultCompletionHandler implements CompletionHandler {
266+
267+ private final int timeLimit ;
268+ private final CountDownLatch latch ;
269+
270+ DefaultCompletionHandler (int timeLimit , int countLimit ) {
271+ this .timeLimit = timeLimit ;
272+ this .latch = new CountDownLatch (countLimit <= 0 ? 1 : countLimit );
273+ }
274+
275+ @ Override
276+ public void waitForCompletion () throws InterruptedException {
277+ if (timeLimit <= 0 ) {
278+ this .latch .await ();
279+ } else {
280+ this .latch .await (timeLimit , TimeUnit .SECONDS );
281+ }
282+ }
283+
284+ @ Override
285+ public void countDown () {
286+ latch .countDown ();
287+ }
288+ }
289+
290+ static class NoLimitCompletionHandler implements CompletionHandler {
291+
292+ private final CountDownLatch latch = new CountDownLatch (1 );
293+
294+ @ Override
295+ public void waitForCompletion () throws InterruptedException {
296+ latch .await ();
297+ }
298+
299+ @ Override
300+ public void countDown () { }
301+ }
302+
303+
254304}
0 commit comments