public synchronized void unregister(MeshRuleListener listener) {
        if (listener == null) {
            return;
        }
        Set<MeshRuleListener> listeners = listenerMap.get(listener.ruleSuffix());
        if (CollectionUtils.isNotEmpty(listeners)) {
            listeners.remove(listener);
        }
        if (CollectionUtils.isEmpty(listeners)) {
            listenerMap.remove(listener.ruleSuffix());
        }
    }
@Test
    void unregister() {
        MeshRuleDispatcher meshRuleDispatcher = new MeshRuleDispatcher("TestApp");

        MeshRuleListener listener1 = new MeshRuleListener() {
            @Override
            public void onRuleChange(String appName, List<Map<String, Object>> rules) {}

            @Override
            public void clearRule(String appName) {}

            @Override
            public String ruleSuffix() {
                return "Type1";
            }
        };

        MeshRuleListener listener2 = new MeshRuleListener() {
            @Override
            public void onRuleChange(String appName, List<Map<String, Object>> rules) {}

            @Override
            public void clearRule(String appName) {}

            @Override
            public String ruleSuffix() {
                return "Type1";
            }
        };

        MeshRuleListener listener3 = new MeshRuleListener() {
            @Override
            public void onRuleChange(String appName, List<Map<String, Object>> rules) {}

            @Override
            public void clearRule(String appName) {}

            @Override
            public String ruleSuffix() {
                return "Type2";
            }
        };

        meshRuleDispatcher.register(listener1);
        meshRuleDispatcher.register(listener2);
        meshRuleDispatcher.register(listener3);

        Assertions.assertEquals(
                2, meshRuleDispatcher.getListenerMap().get("Type1").size());
        Assertions.assertTrue(meshRuleDispatcher.getListenerMap().get("Type1").contains(listener1));
        Assertions.assertTrue(meshRuleDispatcher.getListenerMap().get("Type1").contains(listener2));
        Assertions.assertEquals(
                1, meshRuleDispatcher.getListenerMap().get("Type2").size());
        Assertions.assertTrue(meshRuleDispatcher.getListenerMap().get("Type2").contains(listener3));

        meshRuleDispatcher.unregister(listener1);
        Assertions.assertEquals(
                1, meshRuleDispatcher.getListenerMap().get("Type1").size());
        Assertions.assertTrue(meshRuleDispatcher.getListenerMap().get("Type1").contains(listener2));
        Assertions.assertEquals(
                1, meshRuleDispatcher.getListenerMap().get("Type2").size());
        Assertions.assertTrue(meshRuleDispatcher.getListenerMap().get("Type2").contains(listener3));

        meshRuleDispatcher.unregister(listener2);
        Assertions.assertNull(meshRuleDispatcher.getListenerMap().get("Type1"));
        Assertions.assertEquals(
                1, meshRuleDispatcher.getListenerMap().get("Type2").size());
        Assertions.assertTrue(meshRuleDispatcher.getListenerMap().get("Type2").contains(listener3));

        meshRuleDispatcher.unregister(listener3);
        Assertions.assertNull(meshRuleDispatcher.getListenerMap().get("Type1"));
        Assertions.assertNull(meshRuleDispatcher.getListenerMap().get("Type2"));
    }