The AbstractQueuedSynchronizer class provides two methods that can be used to manage the state of the lock. They are the getState() and setState() methods. These methods receive and return an integer value with the state of the lock. You could have used them instead of the AtomicInteger attribute to store the state of the lock.
The Java Concurrency API provides another class to implement synchronization mechanisms. It's the AbstractQueuedLongSynchronizer class, which is equivalent to AbstractQueuedSynchronizer but uses a long attribute to store the state of the threads.