title: Why do asynchronous channels in Java's NIO.2 require these pauses?
body: <p>I've written minimal example, but it's still too long, so let me know I should post the link to Pastebin instead.</p>
  
  <p>Server:</p>
  
  <pre><code>import java.io.IOException;
  import java.net.InetSocketAddress;
  import java.net.StandardSocketOptions;
  import java.nio.ByteBuffer;
  import java.nio.channels.AsynchronousServerSocketChannel;
  import java.nio.channels.AsynchronousSocketChannel;
  import java.nio.channels.CompletionHandler;
  
  public class Srv {
      static final int    PORT = 9001;
      static final String HOST = "127.0.0.1";
      public static void runInstance() {
          try (AsynchronousServerSocketChannel asynchronousServerSocketChannel =
                       AsynchronousServerSocketChannel.open()) {
              if (asynchronousServerSocketChannel.isOpen()) {
                  asynchronousServerSocketChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024);
                  asynchronousServerSocketChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
                  asynchronousServerSocketChannel.bind(new InetSocketAddress(HOST, PORT));
                  System.out.println(String.format("Launched master on %s:%d", HOST, PORT));
  
                  asynchronousServerSocketChannel.accept(null, new CompletionHandler&lt;AsynchronousSocketChannel, Void&gt;() {
                      @Override
                      public void completed(AsynchronousSocketChannel result, Void attachment) {
                          asynchronousServerSocketChannel.accept(null, this);
                          try {
                              result.read(ByteBuffer.allocate(1024));
                              System.out.println("Conn from:" + result.getRemoteAddress());
                          } catch (Exception exn) {
                              exn.printStackTrace();
                          } finally {
                              try {
                                  result.close();
                              } catch (IOException exn) {
                                  exn.printStackTrace();
                              }
                          }
                      }
                      @Override
                      public void failed(Throwable exn, Void attachment) {
                          asynchronousServerSocketChannel.accept(null, this);
                          throw new UnsupportedOperationException("can't accept");
                      }
                  });
                  System.in.read();
              } else {
                  System.out.println("The asynchronous server-socket channel cannot be opened");
              }
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  
  }
  </code></pre>
  
  <p>Client:</p>
  
  <pre><code>import java.io.IOException;
  import java.net.InetSocketAddress;
  import java.net.StandardSocketOptions;
  import java.nio.ByteBuffer;
  import java.nio.channels.AsynchronousSocketChannel;
  import java.nio.channels.CompletionHandler;
  
  import static java.lang.Thread.sleep;
  
  public class Wrk {
      static final int    PORT = 9001;
      static final String HOST = "127.0.0.1";
      public static void runInstance() throws InterruptedException {
          sleep(1000); //HERE
          try(AsynchronousSocketChannel asynchronousSocketChannel = AsynchronousSocketChannel.open()) {
              if (asynchronousSocketChannel.isOpen()) {
                  asynchronousSocketChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024);
                  asynchronousSocketChannel.setOption(StandardSocketOptions.SO_SNDBUF, 1024);
                  asynchronousSocketChannel.setOption(StandardSocketOptions.SO_KEEPALIVE, true);
                  asynchronousSocketChannel.connect(new InetSocketAddress(HOST, PORT), null,
                      new CompletionHandler&lt;Void, Void&gt;() {
                          @Override
                          public void completed(Void result, Void attachment) {
                              try {
                                  System.out.println("Connected to: " + HOST + PORT);
                                  asynchronousSocketChannel.read(ByteBuffer.allocate(1024)).get();
                              } catch (Exception exn) {
                                  exn.printStackTrace();
                              } finally {
                                  try {
                                      asynchronousSocketChannel.close();
                                  } catch (IOException exn) {
                                      exn.printStackTrace();
                                  }
                              }
                          }
  
                          @Override
                          public void failed(Throwable throwable, Void o) {
                              System.out.println("Connection cannot be established");
                          }
                      });
                  sleep(1000); //AND HERE
              } else {
                  System.out.println("The asynchronous socket channel cannot be opened");
              }
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p>Boilerplate to run:</p>
  
  <pre><code>public class Main {
      public static void main(String[] args) throws InterruptedException {
          Thread srv = new Thread(new Runnable() {
              @Override
              public void run() {
                  Srv.runInstance();
              }
          });
          srv.start();
          Thread wrk1 = new Thread(new Runnable() {
              @Override
              public void run() {
                  try {
                      Wrk.runInstance();
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          });
          wrk1.start();
      }
  }
  </code></pre>
  
  <p>So, if I have the code like this, it gives me the following output:</p>
  
  <pre><code>Launched master on 127.0.0.1:9001
  Connected to: 127.0.0.1 9001
  Conn from:/127.0.0.1:50415
  </code></pre>
  
  <p>But if I remove those <code>sleep()</code>s in <code>Srv.runInstance()</code>, I get:</p>
  
  <pre><code>Connection cannot be established
  Launched master on 127.0.0.1:9001
  Conn from:/127.0.0.1:50438
  </code></pre>
  
  <p>So, does that mean that client connects to server, but server refuses? I don't clearly understand what happens here and documentation is rather poor, so I don't know where to look for solutions.</p>