title: NIO Selector: How to properly register new channel while selecting
body: <p>I have a subclassed <code>Thread</code> with a private <code>Selector</code> and a public <code>register(SelectableChannel channel, ...)</code> method that allows other threads to register channels to the selector.</p>
  
  <p>As answered <a href="https://stackoverflow.com/a/3191377/589008">here</a>, the channel's <code>register()</code> blocks during selector's <code>select()</code> / <code>select(long timeout)</code> so we need to <code>wakeup()</code> the selector.</p>
  
  <p>My thread selects indefinitely (unless it gets interrupted) and it actually manages to get into the next select before channel's <code>register()</code> is called. So I thought I use a simple lock with <code>synchronized</code> blocks  to ensure the <code>register()</code> happens first.</p>
  
  <p>The code: (irrelevant code removed for readability)</p>
  
  <pre><code>public class SelectorThread extends Thread {
    ...
  
    public void register(SelectableChannel channel, Attachment attachment) throws IOException {
      channel.configureBlocking(false);
      synchronized (this) { // LOCKING OCCURS HERE
        selector.wakeup();
        channel.register(selector,
                         SelectionKey.OP_READ,
                         attachment);
      }
    }
  
    @Override
    public void run() {
      int ready;
      Set&lt;SelectionKey&gt; readyKeys;
      while (!isInterrupted()) {
        synchronized (this) {} // LOCKING OCCURS HERE
  
        try {
          ready = selector.select(5000);
        } catch (IOException e) {
          e.printStackTrace();
          continue;
        }
  
        if (ready == 0) {
          continue;
        }
  
        readyKeys = selector.selectedKeys();
  
        for (SelectionKey key : readyKeys) {
          readyKeys.remove(key);
  
          if (!key.isValid()) {
            continue;
          }
  
          if (key.isReadable()) {
            ...
          }
        }
      }
    }
  }
  </code></pre>
  
  <p>This simple lock allows <code>register()</code> to happen before the thread continues with the next select loop. As far as I tested, this works as supposed.</p>
  
  <p><strong>Questions:</strong>
  Is that a "good" way to do it or are there any serious downsides to that? Would it be better to use a List or Queue (as suggested <a href="https://stackoverflow.com/a/2179612/589008">here</a>) to store channels for registration, or a more sophisticated lock like <a href="https://stackoverflow.com/a/1112809/589008">this</a> instead? What would the Pros/Cons of that be? Or are there any "even better" ways?</p>