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

发布于 2022-09-13 00:14:21 字数 1125 浏览 8 评论 0

  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中的代码如何理解

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笑梦风尘 2022-09-20 00:14:21

我没看过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;
         }
     }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文