def SynchronizedClassMethod(*locks_attr_names, **kwargs):
    locks_attr_names = [
        lock_name for lock_name in locks_attr_names if lock_name
    ]
    if not locks_attr_names:
        raise ValueError("The lock names list can't be empty")
    if "sorted" not in kwargs or kwargs["sorted"]:
        locks_attr_names = list(locks_attr_names)
        locks_attr_names.sort()
    def wrapped(method):
        @functools.wraps(method)
        def synchronized(self, *args, **kwargs):
            locks = [getattr(self, attr_name) for attr_name in locks_attr_names]
            locked = collections.deque()
            i = 0
            try:
                for lock in locks:
                    if lock is None:
                        raise AttributeError(
                            "Lock '{0}' can't be None in class {1}".format(
                                locks_attr_names[i], type(self).__name__
                            )
                        )
                    i += 1
                    lock.acquire()
                    locked.appendleft(lock)
                return method(self, *args, **kwargs)
            finally:
                for lock in locked:
                    lock.release()
                locked.clear()
                del locks[:]
        return synchronized
    return wrapped