1

別のスレッドでブロック読み取りを実行しながら、ソケット上の 1 つのスレッドから非ブロック書き込みを実行しようとして、Android アプリを開発しています。私はSocketChannelのドキュメントを調べて、configureBlockingが正確に何をするのかを理解しようとしています。具体的には、ノンブロッキング SocketChannel があり、関連する Socket に socketChannel.socket() でアクセスする場合、その Socket も何らかの方法でノンブロッキングですか? それともブロッキングですか?

言い換えれば、非ブロッキング方向に非ブロッキング SocketChannel を持ち、他の方向に関連する SocketChannel を使用することで、1 つのブロッキング方向と 1 つの非ブロッキング方向の効果を得ることができますか?

4

1 に答える 1

0

Socketにが関連付けられている場合、そのSocketChannelから直接読み取ることはできませんInputStream。あなたは得るでしょうIllegalBlockingModeExceptionここを参照してください。

ブロックしない SocketChannel をセレクタに登録し、select()またはselect(long timeout)を使用してブロックできます。これらのメソッドは通常、登録されたチャネルの準備が整うまで (またはタイムアウトが期限切れになるまで) ブロックします。

セレクターを使用しないスレッドの場合、チャネルは引き続き非ブロックです。

ここから変更された例:

Selector selector = Selector.open();
channel.configureBlocking(false);

// register for OP_READ: you are interested in reading from the channel
channel.register(selector, SelectionKey.OP_READ);

while (true) {
  int readyChannels = selector.select(); // This one blocks...

  // Safety net if the selector awoke by other means
  if (readyChannels == 0) continue;

  Set<SelectionKey> selectedKeys = selector.selectedKeys();
  Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

  while (keyIterator.hasNext()) {
    SelectionKey key = keyIterator.next();

    keyIterator.remove();

    if (!key.isValid()) {
      continue;
    } else if (key.isAcceptable()) {
        // a connection was accepted by a ServerSocketChannel.
    } else if (key.isConnectable()) {
        // a connection was established with a remote server.
    } else if (key.isReadable()) {
        // a channel is ready for reading
    } else if (key.isWritable()) {
        // a channel is ready for writing
    }
  }
}
于 2012-07-05T14:56:32.730 に答える