I'm working with a framework that requires a callback when sending a request. Each callback has to implement this interface. The methods in the callback are invoked asynchronously.
public interface ClientCallback<RESP extends Response>
{
  public void onSuccessResponse(RESP resp);
  public void onFailureResponse(FailureResponse failure);
  public void onError(Throwable e);
}
To write integration tests with TestNG, I wanted to have a blocking callback. So I used a CountDownLatch to synchronize between threads.
Is the AtomicReference really needed here or is a raw reference okay? I know that if I use a raw reference and a raw integer (instead of CountDownLatch), the code wouldn't work because visibility is not guaranteed. But since the CountDownLatch is already synchronized, I wasn't sure whether I needed the extra synchronization from AtomicReference. Note: The Result class is immutable.
public class BlockingCallback<RESP extends Response> implements ClientCallback<RESP>
{
  private final AtomicReference<Result<RESP>> _result = new AtomicReference<Result<RESP>>();
  private final CountDownLatch _latch = new CountDownLatch(1);
  public void onSuccessResponse(RESP resp)
  {
    _result.set(new Result<RESP>(resp, null, null));
    _latch.countDown();
  }
  public void onFailureResponse(FailureResponse failure)
  {
    _result.set(new Result<RESP>(null, failure, null));
    _latch.countDown();
  }
  public void onError(Throwable e)
  {
    _result.set(new Result<RESP>(null, null, e));
    _latch.countDown();
  }
  public Result<RESP> getResult(final long timeout, final TimeUnit unit) throws InterruptedException, TimeoutException
  {
    if (!_latch.await(timeout, unit))
    {
      throw new TimeoutException();
    }
    return _result.get();
  }
 
     
     
     
     
    