关于java与cpu内核的疑惑

        一直以来都有这样一个疑惑,即为什么多线程可以提高程序的运行效率,因为无论开多少线程,都是基于cpu切片时间的,理论上讲,无论开多少线程,由于cpu线程间切换的缘故,其效率都应该不如单线程。

        其实这个问题可以分两部分看:

        1.程序在运行过程中,cpu不总是满负荷的。假设cpu只有单核,由于各种各样的原因,总是会导致IO资源的阻塞,比如网络太慢,业务代码使用bio操作资源,web容器使用阻塞式的方法处理请求等等,IO资源被阻塞就相当于线程被阻塞,会导致cpu空闲,无法最大化利用cpu资源。所以搞个线程池,多线程抢占cpu时间,减少cpu空闲,也就提高了系统性能。在单核cpu上,如果程序完全没有任何阻塞,那么多线程是没有任何意义的。

        2.linux是基于线程调度的。也就是说虽然多线程都存在于一个jvm进程中,但线程间的调度可以被分散在多个cpu内核上,这是操作系统对线程的调度,和jvm已经关系不大了,这样可以充分的利用多核cpu提高性能。

        就像传统的web容器tomcat这种,tomcat8之前默认使用阻塞的bio,基于线程池的模型,每过来一个请求都会分配一个线程进行处理,如果超出maxThread设置的数量,则会把请求放到一个缓冲队列里等待处理,同样如果超出了这个队列的最大容量,则会直接报拒绝访问错误给客户端。tomcat8以后默认使用nio,不会阻塞socket连接,一定程度上提高了性能,但同样也是每发过来一个请求就给他分配一个线程,这里的线程仍然是阻塞式的,不适合高性能高并发的场景,这时可以用servlet3.0提供的异步servlet,将web容器的请求线程和业务线程分开,tomcat的请求线程不会被阻塞,也无需等待业务线程的处理情况,最大化利用非阻塞提高性能。但需要你手动实现并管理业务线程池,像spring5的webflux已经帮你封装好了。

猜你喜欢

转载自blog.csdn.net/hfismyangel/article/details/80894854
今日推荐