2017-06-02 13 views
1

Java NIO.2 Gurusは、Thread.sleep(...)行をコメントアウトしているときに、なぜこのコードが機能しないのか説明できます。Java NIO.2 CompletetionHandlerが到達しない

そして、プログラムが終了するまで非同期操作を処理するようにJVMに指示するにはどうすればよいですか?

import java.net.InetSocketAddress; 
import java.nio.ByteBuffer; 
import java.nio.channels.AsynchronousSocketChannel; 
import java.nio.channels.CompletionHandler; 

public class Main { 
    public static void main(String[] args) { 
     try { 
      AsynchronousSocketChannel channel = AsynchronousSocketChannel.open(); 
      channel.connect(new InetSocketAddress("www.yahoo.com", 80), 
        null, new CompletionHandler<Void, Object>() { 
         @Override 
         public void completed(Void result, Object attachment) { 
          System.out.println("Connected"); 

          ByteBuffer buffer = ByteBuffer.wrap("GET http://www.yahoo.com HTTP/1.1\r\n\r\n".getBytes()); 
          channel.write(buffer, null, new CompletionHandler<Integer, Object>() { 
           @Override 
           public void completed(Integer result, Object attachment) { 
            System.out.println("Write completed: " + result.toString()); 

            ByteBuffer buffer = ByteBuffer.allocate(23); 

            channel.read(buffer, null, new CompletionHandler<Integer, Object>() { 
             @Override 
             public void completed(Integer result, Object attachment) { 
              System.out.println("Read completed: " + result.toString()); 
              System.out.println(new String(buffer.array())); 
             } 

             @Override 
             public void failed(Throwable exc, Object attachment) { 
              exc.printStackTrace(); 
             } 
            }); 
           } 

           @Override 
           public void failed(Throwable exc, Object attachment) { 
            exc.printStackTrace(); 
           } 
          }); 
         } 

         @Override 
         public void failed(Throwable exc, Object attachment) { 
          exc.printStackTrace(); 
         } 
        }); 

      Thread.sleep(10000); 

      channel.close(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 
} 

ありがとうございます。

答えて

1

のThread.sleep(...)が削除されたときに、それが動作しない理由:彼はハンドラを接続し、呼び出すする新しいスレッドを作成しconnect(SocketAddress remote, A attachment, CompletionHandler<Void,? super A> handler)

方法。

ソケットが接続される前にすべてのデータが転送されるまで、遅延が発生しません。あなたが他のスレッドを待つ方法を見つける必要があり

にそれを避けるために、どのように

java.util.concurrent.CompletableFuture<V>と例えば

try { 
    CompletableFuture<Boolean> future = new CompletableFuture<Boolean>(); 

    AsynchronousSocketChannel channel = AsynchronousSocketChannel.open(); 
    channel.connect(new InetSocketAddress("www.yahoo.com", 80), 
      null, new CompletionHandler<Void, Object>() { 
       @Override 
       public void completed(Void result, Object attachment) { 
        System.out.println("Connected"); 

        ByteBuffer buffer = ByteBuffer.wrap("GET http://www.yahoo.com HTTP/1.1\r\n\r\n".getBytes()); 
        channel.write(buffer, null, new CompletionHandler<Integer, Object>() { 
         @Override 
         public void completed(Integer result, Object attachment) { 
          System.out.println("Write completed: " + result.toString()); 

          ByteBuffer buffer = ByteBuffer.allocate(23); 

          channel.read(buffer, null, new CompletionHandler<Integer, Object>() { 
           @Override 
           public void completed(Integer result, Object attachment) { 
            System.out.println("Read completed: " + result.toString()); 
            System.out.println(new String(buffer.array())); 

            // 
            future.complete(true); 
           } 

           @Override 
           public void failed(Throwable exc, Object attachment) { 
            exc.printStackTrace(); 
            // 
            future.complete(false); 
           } 
          }); 
         } 

         @Override 
         public void failed(Throwable exc, Object attachment) { 
          exc.printStackTrace(); 
          // 
          future.complete(false); 
         } 
        }); 
       } 

       @Override 
       public void failed(Throwable exc, Object attachment) { 
        exc.printStackTrace(); 
        // 
        future.complete(false); 
       } 
      }); 
    // Wait until the other Threads are finished 
    System.out.println("Successs: "+future.get(10, TimeUnit.SECONDS)); 
    channel.close(); 
} catch (Exception ex) { 
    ex.printStackTrace(); 
} 

またはあなたの場合あなたは、単に(ハンドラなし)AsynchronousSocketChannelこの方法を扱うことができます。

try { 
    AsynchronousSocketChannel channel = AsynchronousSocketChannel.open(); 
    Future<Void> futureConnect = channel.connect(new InetSocketAddress("www.yahoo.com", 80)); 
    // wait until connected 
    futureConnect.get(); 
    System.out.println("Connected"); 

    ByteBuffer buffer = ByteBuffer.wrap("GET http://www.yahoo.com HTTP/1.1\r\n\r\n".getBytes()); 
    Future<Integer> futureWrite = channel.write(buffer); 
    // wait until all data is written 
    Integer resultWrite = futureWrite.get(); 
    System.out.println("Write completed: " + resultWrite.toString()); 

    ByteBuffer bufferRead = ByteBuffer.allocate(23); 
    Future<Integer> futureRead = channel.read(bufferRead); 
    // wait ... 
    Integer resultRead = futureRead.get(); 
    System.out.println("Read completed: " + resultRead.toString()); 
    System.out.println(new String(bufferRead.array())); 

    // finnished now the channel can be closed 
    channel.close(); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 
関連する問題