记录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();