多路复用器java代码 多路复用器java代码怎么写( 三 )


class Handler { // ...
public void run() { // initial state is reader
socket.read(input);
if (inputIsComplete()) {
process();
sk.attach(new Sender());//状态迁移, Read后变成write, 用Sender作为新的callback对象
sk.interest(SelectionKey.OP_WRITE);
sk.selector().wakeup();
}
}
class Sender implements Runnable {
public void run(){ // ...
socket.write(output);
if (outputIsComplete()) sk.cancel();
}
}
}
```
- 多线程Reacotr
处理消息过程放在其多路复用器java代码他线程中执行
```java
class Handler implements Runnable {
// uses util.concurrent thread pool
static PooledExecutor pool = new PooledExecutor(...);
static final int PROCESSING = 3;
// ...
synchronized void read() { // ...
socket.read(input);
if (inputIsComplete()) {
state = PROCESSING;
pool.execute(new Processer()); //使用线程pool异步执行
}
}
synchronized void processAndHandOff() {
process();
state = SENDING; // or rebind attachment
sk.interest(SelectionKey.OP_WRITE); //process完,开始等待write事件
}
class Processer implements Runnable {
public void run() { processAndHandOff(); }
}
}
```
- 使用多个selector
mainReactor只负责处理accept并创建socket , 多个subReactor负责处理读写请求
```java
Selector[] selectors; //subReactors集合, 一个selector代表一个subReactor
int next = 0;
class Acceptor { // ...
public synchronized void run() { ...
Socket connection = serverSocket.accept(); //主selector负责accept
if (connection != null)
new Handler(selectors[next], connection); //选个subReactor去负责接收到的connection
if (++next == selectors.length) next = 0;
}
}
```
#AIO
AIO是真正的异步IO,它于JDK1.7时引入,它和NIO的区别在于:
- NIO仍然需要一个线程阻塞在select方法上,AIO则不需要
- NIO得到数据准备好的消息以后,仍然需要自己把消息复制到用户空间,AIO则是通过操作系统的支持把数据异步复制到用户空间以后再给应用进程发出信号 。
IO多路复用 阻塞IO只能阻塞一个IO操作 , IO复用模型能阻塞多个IO操作,所以才叫多路复用
读数据 :
直到数据全拷贝至User Space后才返回
不断去Kernel做Polling,询问比如读操作是否完成,没完成则read()操作会返回EWOUDBLOCK,需要过一会再尝试执行一次read() 。该模式会消耗大量CPU
之前等待时间主要消耗在等数据到达上 。IO Multiplexing则是将等待数据到来和读取实际数据两个事情分开,好处是通过select()等IO Multiplexing的接口一次可以等待在多个Socket上 。select()返回后,处于Ready状态的Socket执行读操作时候也会阻塞,只是只阻塞将数据从Kernel拷贝到User的时间
首先注册处理函数到SIGIO信号上,在等待数据到来过程结束后,系统触发SGIO信号,之后可以在信号处理函数中执行读数据操作,再唤醒Main Thread或直接唤醒Main Thread让它完成数据读取 。整个过程没有一次阻塞 。
问题:TCP下 , 连接断开/可读/可写等都会产生Signal,并且Signal没有提供好的方法去区分这些Signal到底为什么被触发
AIO是注册一个读任务,直到读任务完全完成后才会通知应用层 。AIO是由内核通知IO操作什么时候完成,信号驱动IO是由内核告知何时启动IO操作
也存在挺多问题,比如如何去cancel一个读任务
除了AIO是异步IO,其他全是同步IO
fd_set: 一个long类型的数组 , 每一位可以表示一个文件描述符
问题 :
返回条件与select一样 。

推荐阅读