code: public static ChannelBuffer sendSynchronousTwoWayMessage(RequestChannel channel,
                                                               final ChannelBuffer request)
              throws TException, InterruptedException
      {
          final ChannelBuffer[] responseHolder = new ChannelBuffer[1];
          final TException[] exceptionHolder = new TException[1];
          final CountDownLatch latch = new CountDownLatch(1);
  
          responseHolder[0] = null;
          exceptionHolder[0] = null;
  
          channel.sendAsynchronousRequest(request, false, new RequestChannel.Listener()
          {
              @Override
              public void onRequestSent()
              {
              }
  
              @Override
              public void onResponseReceived(ChannelBuffer response)
              {
                  responseHolder[0] = response;
                  latch.countDown();
              }
  
              @Override
              public void onChannelError(TException e)
              {
                  exceptionHolder[0] = e;
                  latch.countDown();
              }
          });
  
          latch.await();
  
          if (exceptionHolder[0] != null) {
              throw exceptionHolder[0];
          }
  
          return responseHolder[0];
      }
docs: Sends a single message synchronously, and blocks until the responses is received.
  <p/>
  NOTE: the underlying transport may be non-blocking, in which case the blocking is simulated
  by waits instead of using blocking network operations.
  
  @param request
  @return The response, stored in a ChannelBuffer
  @throws TException           if an error occurs while serializing or sending the request or
  while receiving or de-serializing the response
  @throws InterruptedException if the operation is interrupted before the response arrives