1.IO,多线程和多核
原文:程序有时候需要等待外部的操作,比如输入和输出。并且在等待的时候不可能进行有价值的工作。在等待的时候,让其他程序运行会提高效率。
这里可以把IO比作烧开水,其他操作比作看报纸。如果多线程的话,可以在等水烧开的同时看报纸。
1.单核
对于单CPU的情况,多线程也可以充分利用。比如有两个线程,一个线程在做BIO,另一个线程可以利用CPU。
2.多核
对于多CPU的情况,多线程可以充分利用CPU。如果有4个CPU,只有一个线程,那么相当于放弃了75%的CPU资源,因为只有一个CPU被利用了起来。
2.连接数和线程
连接数和线程不是一个概念。
1.tomcat接收http请求
用tomcat来举例,对于tomcat容器,我们可以设置连接数,还可以设置线程数(tomcat前端线程)。
如果连接数满了,那么新来的访问将无法获取连接。
tomcat线程(http-bio)可以将用户的请求任务(已经创建连接)发送给我们后端。
这时如果后端应用没有再开线程处理的话,就会使用该前端线程来继续处理业务流程。如果后端有线程池的话,该tomcat线程会被释放,重新去接收用户的请求。
2.异步servlet
使用异步servlet的时候,后端在写代码的时候其实是按照同步的方式来写的,只是实用了startAsync,具体的异步流程是tomcat来做的。
3.dubbo
dubbo和tomcat类似,一次dubbo的rpc调用,dubbo线程会接收请求,如果后端没有其他线程来处理的话,则使用该dubbo线程来处理业务流程。
4.异步dubbo
异步dubbo在使用的时候,我们写代码是按照异步的方式来写的。
5.几个疑问
tomcat的连接数和线程数怎么平衡,如果连接数限制设置过大,tomcat线程执行业务过慢的话,会打爆tomcat线程吗?
异步servlet具体怎么实现的,可以让我们的业务代码可以按照同步来写?
异步dubbo的异步长连接?
3.非阻塞IO
1.非阻塞使用场景
程序在读取Socket时如果没有可用数据,read方法会一直阻塞着直到有数据可用。如果是一个单线程的程序,那么不只是当前处理停止了,在该时段所有的请求响应都停止了。
为了避免这个问题,可以使用非阻塞IO,这样程序会更复杂些。
2.操作系统的非阻塞
Unix系统的select和poll,为了访问这些机制,java提供了NIO。
3.大量线程
今天的操作系统,使得大量的线程存在称为可能,每线程每客户的模型也指日可待。