记录Apache Curator NodeCache的一个坑

记录Apache Curator NodeCache的一个坑

NodeCache nodeCache = new NodeCache(client, path.fullPath());
nodeCache.start(true);

System.out.println(nodeCache.getCurrentData());  // data是1

client.setData()
                .forPath(path.fullPath(), new byte[]{2});    // data是2

System.out.println(nodeCache.getCurrentData());

nodeCache.close();

预期结果是第一次print看到data是1,改变了节点的数据之后,第二次print出来应该是新数据。
NodeCache应该在节点的数据变化的时候,自动更新内部的data。
然而实际运行结果,第一次和第二次都是1

原因是NodeCache更新内部data是在另一个线程做的(后面称作更新线程),主线程比更新线程要快,主线程走到第二个print的时候,更新线程还没更新好,所以主线程看到的还是更新前的数据。

解决方法

nodeCache.getCurrentData这一个操作不在主线程做,用listener处理node数据变化之后的业务逻辑。

nodeCache.getListenable().addListener(() -> {
            System.out.println(nodeCache.getCurrentData());
            // 业务逻辑
        });

如果需要等listener线程处理完之后,主线程才可以退出,可以用countdownlatch之类的线程同步方式。

CountDownLatch latch = new CountDownLatch(1);
NodeCache nodeCache = new NodeCache(client, path.fullPath());
nodeCache.getListenable().addListener(() -> {
            System.out.println(nodeCache.getCurrentData());  // 更新后的数据
            latch.countDown();
            // 业务逻辑
        });

nodeCache.start(true);

System.out.println(nodeCache.getCurrentData());  // 初始数据
client.setData()
                .forPath(path.fullPath(), new byte[]{2});
latch.await();

nodeCache.close();

你可能感兴趣的:(记录Apache Curator NodeCache的一个坑)