private void watchDataChange( final ZKClientService zkClient, final String path, final Semaphore semaphore, final AtomicReference<String> stateMatch) { Futures.addCallback( zkClient.getData( path, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getType() == Event.EventType.NodeDataChanged) { watchDataChange(zkClient, path, semaphore, stateMatch); } } }), new FutureCallback<NodeData>() { @Override public void onSuccess(NodeData result) { String content = new String(result.getData(), Charsets.UTF_8); JsonObject json = new Gson().fromJson(content, JsonElement.class).getAsJsonObject(); if (stateMatch.get().equals(json.get("state").getAsString())) { semaphore.release(); } } @Override public void onFailure(Throwable t) { exists(); } private void exists() { Futures.addCallback( zkClient.exists( path, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getType() == Event.EventType.NodeCreated) { watchDataChange(zkClient, path, semaphore, stateMatch); } } }), new FutureCallback<Stat>() { @Override public void onSuccess(Stat result) { if (result != null) { watchDataChange(zkClient, path, semaphore, stateMatch); } } @Override public void onFailure(Throwable t) { LOG.error(t.getMessage(), t); } }); } }); }