在上一个基础上实现阻塞式队列,拿不到队列数据时,进行阻塞直到拿到数据,继承之前的类对poll方法升级,在队列为空时利用CounDownLatch进行await阻塞,并加入监听子节点变化的事件,coundown()解除阻塞
@Override
public T poll() throws InterruptedException, KeeperException {
boolean flag=true;
while (flag){
//结束在latch上的等待,再来一次
final CountDownLatch latch=new CountDownLatch(1);
final Watcher childListener=new Watcher() {
@Override
@SneakyThrows
public void process(WatchedEvent event) {
//监听子节点列表的 变更情况
if (event.getType()==Event.EventType.NodeChildrenChanged){
//队列变化
latch.countDown();
}
//重新绑定监听
zkClient.getChildren(root,this);
}
};
zkClient.getChildren(root,childListener);
try {
T node=super.poll(); //调用父类的poll方法获取队列数据
if(node!=null){
return node;
}else {
//拿不到队列数据则在latch里await
latch.await();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
当队列空时会阻塞,直到有数据才解开阻塞
非阻塞式(返回null)与阻塞式相比,后者是让CPU自旋,前者返回空后依然会执行后面的代码。