use of java.util.concurrent.SynchronousQueue in project cdap by caskdata.
the class AbstractProgramController method addListener.
@Override
public final Cancellable addListener(Listener listener, final Executor listenerExecutor) {
Preconditions.checkNotNull(listener, "Listener shouldn't be null.");
Preconditions.checkNotNull(listenerExecutor, "Executor shouldn't be null.");
final ListenerCaller caller = new ListenerCaller(listener, listenerExecutor);
final Cancellable cancellable = new Cancellable() {
@Override
public void cancel() {
// Simply remove the listener from the map through the executor and block on the completion
Futures.getUnchecked(executor.submit(new Runnable() {
@Override
public void run() {
listeners.remove(caller);
}
}));
}
};
try {
// Use a synchronous queue to communicate the Cancellable to return
final SynchronousQueue<Cancellable> result = new SynchronousQueue<>();
// Use the single thread executor to add the listener and call init
executor.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
Cancellable existing = listeners.get(caller);
if (existing == null) {
listeners.put(caller, cancellable);
result.put(cancellable);
caller.init(getState(), getFailureCause());
} else {
result.put(existing);
}
return null;
}
});
return result.take();
} catch (Exception e) {
// there shouldn't be interrupted exception as well.
throw Throwables.propagate(Throwables.getRootCause(e));
}
}
Aggregations