Reactor

Reactor模式1:
在这里插入图片描述
Reactor模式2:
在这里插入图片描述
主线程:注册serverSocket类(设置为非阻塞模式,即调用accept、read、write等方法时不会阻塞,而是立刻返回一个结果,比如没有连接就返回没有连接,有连接了就返回有连接了)和事件和有了事件以后要开启的线程类accptor到selector上放到map里,
主线程开启一个循环,循环里的第一个方法是selector的select方法,selector调用select方法(我觉得是一个循环方法)来循环检测map里的事件是否已就绪即(循环调用map里类的事件方法,如果有连接了代表就绪了,注意主要是不会阻塞这个特性在起大作用,如果是阻塞的,那么一调用accept就被阻塞住了。假如多个连接请求过来了但还没完成三次握手就返回还没就绪,selector继续轮询map中的其他类比如读写事件的类,如果有一个连接三次握手完成了,但这个类没被轮询到就不会执行这个类的相应的线程,但因为map里所有类的事件对应的方法都是非阻塞的,所以轮询很快,基本瞬间完成一次轮询,一旦轮询到就绪的事件了,就会退出轮询,否则一直轮询,即select方法会阻塞主,除非map里的某个事件就绪了就返回),一旦有连接select方法返回,继续该线程里的下一个动作,开启accpetor(也有可能是读、写子线程,看哪个事件被触发了,但现在因为没有注册读写事件,所以肯定不会开启读写子线程)子线程(瞬间不会阻塞)。 主线程任务结束,继续selcet轮询。

accptor子线程:获得连接对象socket(注意这里调用accept方法也不会被阻塞,并且select轮询的时候已经确认有连接了,这里很快会返回一个socket对象),并新建一个handler类(持有当前sockert引用)的读事件和有了读事件后要开启的线程类注册到主线程里的selcetor类上。acceptor线程结束。

这时selector的map中有两个事件了,一个是accept,一个是读。因为主线程继续调用selector的select方法继续轮询map里的类,如果此事读事件被触发,就会按照上面类似所述在主线程里开启一个读事件对应的子线程,此子线程里执行当前socket的读操作,读完后执行业务处理,再新建一个handler类(持有当前socket引用)的写事件和有了写事件后要开启的线程类注册到主线程的selector类上。读线程结束,但请注意,因为执行业务处理的代码也再读线程里,所以业务处理很可能阻塞住读线程。

这时selector的map中有3个事件了。一个是accept,一个是读,一个是写,主线程继续调用selector的select方法继续轮询map里的类,如果写事件被触发,在主线程里开启一个写事件对应的子线程,将要写出的数据写出。 写线程结束。

如果再有新的连接进来,再开启一个新的acceptor子线程,获得新的socket对象和新建一个读事件的类实例注册到selector,读事件触发再新建一个新的子线程用来处理读数据和业务处理,再新建一个写事件的类实例注册到selector上。写事件触发再新建一个新的子线程用来写数据。 如此主线程循环下去。

Reactor模式3:
在这里插入图片描述
这个模型和上面第二个模型相比,主要是在读子线程里,在从socket中读完数据后,执行业务处理时有所不同,模式二里读操作和执行业务处理代码都在一个子线程里执行,业务处理可能阻塞住读子线程,如果阻塞住,可以想象下,如果同时有很多读事件被触发,那么就会开很多读子线程,但这些线程又被业务处理阻塞住没法快速结束,导致同一时间系统里有很多读子线程存在,占用大量资源。而模式三里,在读子线程里,读完数据后,我们使用线程池新开一个业务子线程用来处理业务数据。模式三里,读子线程,读完后,开启一个业务线程,读子线程结束。这样读子线程不会被业务处理阻塞住。而在业务子线程里,执行业务操作,业务操作玩后,新建一个写事件的类注册到主线程的selector上。 同时呢,因为开启子线程是使用的线程池技术,所以呢,即使同时又很多读事件触发,假如线程池中最多10个线程,那么线程池在用这10个创建完子线程后,不再新建线程。其他读子线程里的开启业务子线程,会把开启的任务到线程池的任务队列中等待线程池中的空余线程,然后读子线程结束,所以系统中不会存在很多个业务子线程,顶多10个。其他的都在线程池中的任务对垒中等待线程池有空闲线程。 线程池技术需要再看看。

但我还有一点不明白,就是读事件和写事件在什么情况下被触发呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值