New I/O

IRC のクライアントだと 1対のInput/Outputが通常の状態なので、それほど性能は要らないかもしれないけど、気になったのでメモ。

public void run() {
  while (true) {
    // Execute all the pending tasks.
    doInvocations();
    
    // Time to terminate? 
    if (closeRequested) {
      return;
    }
    
    int selectedKeys = selector.select();
    if (selectedKeys == 0) {
      // Go back to the beginning of the loop 
      continue;
    }
     
    // Dispatch all ready I/O events
    Iterator it = selector.selectedKeys().
      iterator();
    while (it.hasNext()) {
      SelectionKey sk = (SelectionKey)it.next();
      it.remove();      
      // Obtain the interest of the key
      int readyOps = sk.readyOps();
      // Disable the interest for the operation
      // that is ready. This prevents the same 
      // event from being raised multiple times.
      sk.interestOps(
        sk.interestOps() & ~readyOps);
          
      // Retrieve the handler associated with 
      // this key
      SelectorHandler handler = 
         (SelectorHandler) sk.attachment();          
        
      // Check what are the interests that are 
      // active and dispatch the event to the 
      // appropriate method.
      if (sk.isAcceptable()) {
        // A connection is ready to be completed
        ((AcceptSelectorHandler)handler).
          handleAccept();
        
      } else if (sk.isConnectable()) {
        // A connection is ready to be accepted            
        ((ConnectorSelectorHandler)handler).
          handleConnect();            
          
      } else {
        ReadWriteSelectorHandler rwHandler = 
          (ReadWriteSelectorHandler)handler; 
        // Readable or writable              
        if (sk.isReadable()) {
          // It is possible to read
          rwHandler.handleRead();              
        }
            
        // Check if the key is still valid, 
        // since it might have been invalidated 
        // in the read handler (for instance, 
        // the socket might have been closed)
        if (sk.isValid() && sk.isWritable()) {
          // It is read to write
          rwHandler.handleWrite();                              
        }
      }
    }
  }
}