/*来源: PPT【Scalable IO in Java.pdf】*/
// Reactor:通过分派适当的处理程序来响应IO事件
class Reactor implements Runnable{
final Selector selector;
final ServerSocketChannel serverSocket;
Reactor(int port) throws IOException{
selector = Selector.open();
serverSocket = ServerSocketChannel.open();
serverSocket.socket().bind(new InetSocketAddress(port));
serverSocket.configureBlocking(false);
SelectionKey sk = serverSocket.register(selector, SelectionKey.OP_ACCEPT);
sk.attach(new Acceptor());
}
public void run(){
try{
while(!Thread.interrupted()){
selector.select();
Set selected = selector.selectedKeys();
Iterator it = selected.iterator();
while(it.hasNext()){
dispatch((SelectionKey)it.next();
}
selected.clear();
}
}catch(IOException ex){}
}
void dispatch(SelectionKey k){
Runnable r = (Runable)(k.attachment());
if(r != null){
r.run();
}
}
class Acceptor implements Runable{ // inner
public void run(){
try{
SocketChannel c = serverSocket.accept();
if(c != null){
new Handler(selector, c);
}
}catch(IOException ex){}
}
}
}
final class Handler implements Runable{
final SocketChannel socket;
final SelectionKey sk;
ByteBuffer input = ByteBuffer.allocate(MAXIN);
ByteBuffer ouput = ByteBuffer.allocate(MAXOUT);
static final int READING = 0, SENDING = 1;
int state = READING;
Handler(Selector sel, SocketChannel c) throws IOException{
socket = c;
c.configureBlocking(false);
// Optionally try first read now
sk = socket.register(sel, 0); // ** 同一个selector **
sk.attach(this);
sk.interestOps(SelectionKey.OP_READ);
sel.wakeup();
}
boolean inputIsComplete(){}
boolean outputIsComplete(){}
void process(){}
public void run(){
try{
if (state == READING) read();
else if (state == SENDING) send();
}catch(IOException ex){}
}
void read() throws IOException{
socket.read(input);
if(inputIsComplete()){
process();
state = SENDING;
// Normally also do first write now
sk.interestOps(SelectionKey.OP_WRITE);
}
}
void send() throws IOException{
socket.write(output);
if(outputIsComplete()){
sk.cancel();
}
}
}