public void start(){ addStage("broadcast", broadcastStageQueue, broadcastStage); } private void addStage(String name, BlockingQueue> queue, ProcessingStage stage) { stagesThreadPool.submit(new Thread(() -> { try { while (!shutdown.get()) { ProcessingContext ctx = queue.take(); ctx = stage.process(ctx); switch (ctx.getNextStage()) { case REPLY: replyStageQueue.put(ctx); break; case HASHING: hashAndValidate(ctx); break; case RECEIVED: receivedStageQueue.put(ctx); break; case MULTIPLE: ImmutablePair, ProcessingContext< ReceivedPayload>> payload = (ImmutablePair, ProcessingContext>) ctx.getPayload(); replyStageQueue.put(payload.getLeft()); receivedStageQueue.put(payload.getRight()); break; case BROADCAST: broadcastStageQueue.put(ctx); break; case ABORT: break; } } } catch (InterruptedException e) { } finally { log.info("{} stage shutdown", name); } }, name + "-stage")); }