@Test
    public void testMessagesDispatchedToDifferentHandlersAreExecutedConcurrently() throws InterruptedException, BrokenBarrierException, TimeoutException {
        final AtomicBoolean threadingIssueDetected = new AtomicBoolean(false);
        final Lock guardLock1 = new ReentrantLock();
        final Lock guardLock2 = new ReentrantLock();
        final CyclicBarrier handlersBarrier = new CyclicBarrier(3);

        ZContext ctx = new ZContext();

        ZMQ.Socket socketOne = ctx.createSocket(ZMQ.PAIR);
        socketOne.bind("inproc://zmsg.test");
        ZMQ.Socket socketTwo = ctx.createSocket(ZMQ.PAIR);
        socketTwo.connect("inproc://zmsg.test");

        ZDispatcher dispatcher = new ZDispatcher();

        ZDispatcher.ZSender senderOne = new ZDispatcher.ZSender();
        dispatcher.registerHandler(socketOne, new ZDispatcher.ZMessageHandler() {

            @Override
            public void handleMessage(ZDispatcher.ZSender sender, ZMsg msg) {
                try {
                    if (guardLock1.tryLock()) {
                        handlersBarrier.await(1, TimeUnit.SECONDS);
                    } else {
                        threadingIssueDetected.set(true);
                    }
                } catch (Exception ex) {
                    threadingIssueDetected.set(true);
                } finally {
                    guardLock1.unlock();
                }
            }
        }, senderOne);

        ZDispatcher.ZSender senderTwo = new ZDispatcher.ZSender();
        dispatcher.registerHandler(socketTwo, new ZDispatcher.ZMessageHandler() {

            @Override
            public void handleMessage(ZDispatcher.ZSender sender, ZMsg msg) {
                try {
                    if (guardLock2.tryLock()) {
                        handlersBarrier.await(1, TimeUnit.SECONDS);
                    } else {
                        threadingIssueDetected.set(true);
                    }
                } catch (Exception ex) {
                    threadingIssueDetected.set(true);
                } finally {
                    guardLock2.unlock();
                }
            }
        }, senderTwo);

        ZMsg msg = new ZMsg();
        ZFrame frame = new ZFrame("Hello");
        msg.addFirst(frame);

        senderOne.send(msg.duplicate());
        senderOne.send(msg.duplicate());
        senderTwo.send(msg.duplicate());
        senderTwo.send(msg.duplicate());

        handlersBarrier.await(1, TimeUnit.SECONDS);
        handlersBarrier.await(1, TimeUnit.SECONDS);

        assertFalse(threadingIssueDetected.get());

        dispatcher.shutdown();
        ctx.destroy();
    }