当我在没有超时的情况下使用select()时,它只会永远挂在select()上。但是,如果我将select(long)与超时一起使用,它会返回并允许我读取数据。 (打印“已读!”)
代码:
package org.nio;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @author admin
*/
public class ServerNode {
public static void main(String[] args) throws Exception {
final ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.bind(new InetSocketAddress(11117));
ssc.configureBlocking(true);
System.out.println("");
int cpus = Math.max(Runtime.getRuntime().availableProcessors(), 3);
System.out.println("cpus: " + cpus);
ExecutorService ex = Executors.newFixedThreadPool(cpus + 1);
final Selector readWriteSel = Selector.open();
ex.submit(() -> {
try {
do {
SocketChannel sc = ssc.accept();
sc.configureBlocking(false);
sc.register(readWriteSel, SelectionKey.OP_READ, sc);
System.out.println("Connected! " + sc.socket().getInetAddress().getHostAddress());
} while (true);
} catch (Exception e) {
e.printStackTrace();
}
});
ex.submit(() -> {
try {
do {
int len = readWriteSel.select();
if (len > 0) {
System.out.println("2");
Iterator<SelectionKey> it = readWriteSel.selectedKeys().iterator();
while (it.hasNext()) {
System.out.println("3");
System.out.println("woke!");
SelectionKey key = it.next();
if (key.isValid() && key.isReadable()) {
SocketChannel sc = (SocketChannel) key.channel();
sc.read(ByteBuffer.allocate(1024 * 50));
System.out.println("read!");
}
it.remove();
}
}
} while (true);
} catch (Exception e) {
e.printStackTrace();
}
});
new Thread() {//client
@Override
public void run() {
try {
Thread.sleep(5000);
Socket s = new Socket("127.0.0.1", 11117);
OutputStream out = s.getOutputStream();
out.write(new byte[1024 * 1024]);
out.flush();
Thread.sleep(10000);
out.write(new byte[1024 * 1024]);
out.flush();
Thread.sleep(1000000);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
System.out.println("Ready");
}
}
要更改以使其不挂起的行:
int len = readWriteSel.select(1000);
我误解了文档,还是应该在有待读取的数据后立即返回select()?
谢谢!