Debezium框架中的这段代码如何解释?

  private static final class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 4982264981922014374L;

        Sync(int count) {
                    (count);
        }

        int getCount() {
            return getState();
        }

        @Override
        protected int tryAcquireShared(int acquires) {
            return (getState() == 0) ? 1 : -1;
        }

        @Override
        protected boolean tryReleaseShared(int releases) {
            // Increment or decrement count; signal when transition to zero
            for (;;) {
                int c = getState();
                if (c == 0 && releases >= 0) {
                    return false;
                }
                int nextc = c - releases;
                if (nextc < 0) {
                    nextc = 0;
                }
                if (compareAndSetState(c, nextc)) {
                    return nextc == 0;
                }
            }
        }
    }

问题:
(1)tryAcquireShared方法内部为什么要用getState是否等于零来判断是否获取锁成功?
(2)tryReleaseShared中的代码如何理解

阅读 1.3k
1 个回答

我没看过Debezium的源码哈,不过我看过AbstractQueuedSynchronizer的一些实现,而且这个代码与CountDownLatch有点像,所以说大概,给你个参考。

  1. getState(),这个方法是获取状态,这个状态表示锁的重入次数或者一个状态的计数,如ReentrantLock就是重入一次state加1,释放一次减1。还有如CountDownLatch就是创建的时候设置state,每次countDown,这个state就减1,await把主线程阻塞住,某个线程在countDown后发现state等于0,就去释放主线程。
  2. 问题中的这个 return (getState() == 0) ? 1 : -1;不是用于判断是否获取锁成功的,就是判断state等不等于0,这就与各自的逻辑相关了。如CountDownLatch中只用于在await方法中判断主线程是否需要阻塞。因为调用await的时候state可能已经清零,就不用阻塞主线程了。
  3. protected boolean tryReleaseShared(int releases) {
     // Increment or decrement count; signal when transition to zero
     for (;;) {
         //获取state,这个state表示一个状态的计数
         int c = getState();
         //如果状态等于0,表示没有线程获取锁,在没有线程获取锁的情况下又调用了
         //释放方法,所以返回释放失败
         //但是这里又&&releases >= 0,意思是releases小于0也不会立即返回false
         //那么这个方法理论上可以用来增加计数
         if (c == 0 && releases >= 0) {
             return false;
         }
         //状态减去释放的次数
         int nextc = c - releases;
         //releases可以是任何值,这里表示即使释放计数超出了存在的计数,也不重要。
         if (nextc < 0) {
             nextc = 0;
         }
    
         //这个方法内部会获取state的偏移量,
         //并使用原子方法操作比较和设置,如果state==c那么把state设置为nextc,设置成功返回true,
         //如果此时有其他线程改变了state,使state!=c,返回false
         //这个方法也用于获取锁,一个线程如果成功的把state从0改为1,返回true,那么表示获取锁成功。
         //上方for (;;)这个死循环也是用于如果这个方法返回false,表示有其他线程改变了状态,那么再次重试,直到设置成功。
         if (compareAndSetState(c, nextc)) {
             //如果返回true,表示计数归0,这个归0就与各自的功能相关了,
             //如CountDownLatch会去释放主线程,ReentrantLock会去唤醒队列中排队的线程。
             return nextc == 0;
         }
     }
    }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题