private void removeMatching(Iterator<Node> it, Predicate<? super Node> predicate, Difference<Node> result) {
        while (it.hasNext()) {
            Node node = it.next();

            // if the predicate passes, remove the node from the set & record to results
            if (predicate.test(node)) {
                it.remove();
                result.recordChange(ChangeType.REMOVE, node);

                // update inheritance map too if necessary
                if (node instanceof InheritanceNode && node.getValue()) {
                    SortedSet<InheritanceNode> inhNodes = this.inheritanceMap.get(node.getContexts());
                    if (inhNodes != null) {
                        inhNodes.remove(node);
                    }
                }
            }
        }
    }
This lock is used whilst performing mutations, but *not* reads.

The maps themselves are thread safe, so for querying, we just allow
the read methods to do whatever they want without any locking.
However, we want mutations to be atomic, so we use the lock to ensure that happens.
common/src/main/java/me/lucko/luckperms/common/model/nodemap/NodeMapMutable.java