在上篇:子线程使用消息机制更新UI将到AsyncTask
现在已经被废弃的时候提到,在Android
中使用多线程建议使用ThreadPoolExecutor
线程池,或者使用JUC
其他类,以及最后的协程方式。
对于ThreadPoolExecutor
等在线程池ThreadPoolExecutor已经介绍过了,这里不再介绍。
协程,英文Coroutines
,是一种比线程更加轻量级的存在。正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。
最重要的是,协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在用户态执行)。这样带来的好处就是性能得到了很大的提升,不会像线程切换那样消耗资源。协程的暂停完全由程序控制,线程的阻塞状态是由操作系统内核来进行切换。因此,协程的开销远远小于线程的开销。
具体的实现比如Python
语言的yield
,Java
语言并没有对协程的原生支持,但是某些开源框架模拟出了协程的功能,比如Kilim
框架。
协程运行在线程之上,当一个协程执行完成后,可以选择主动让出,让另一个协程运行在当前线程之上。协程并没有增加线程数量,只是在线程的基础之上通过分时复用的方式运行多个协程,而且协程的切换在用户态完成,切换的代价比线程从用户态到内核态的代价小很多。
我们只需要启动100
个线程,每个线程上运行100
个协程,这样不仅减少了线程切换开销,而且还能够同时处理10000
个读取数据库的任务。
协程只有在等待IO
的过程中才能重复利用线程。实际上操作系统并不知道协程的存在,它只知道线程,因此在协程调用阻塞IO
操作的时候,操作系统会让线程进入阻塞状态,当前的协程和其它绑定在该线程之上的协程都会陷入阻塞而得不到调度,这往往是不能接受的。
因此在协程中不能调用导致线程阻塞的操作。也就是说,协程只有和异步IO结合起来,才能发挥最大的威力。
看到这里,我突然想起之前的项目中,并没有特别配置后台的并发访问量,但是却支持几千人同时在线评教,故而就百度了下:
因为SpringBoot
内置Tomcat
,在默认设置中Tomcat
的最大线程数是200
,最大连接数是10000
。
支持的并发量是指连接数,200
个线程如何处理10000
条连接的?
Tomcat
有两种处理连接的模式,一种是BIO
,一个线程只处理一个连接,另一种就是NIO
,一个线程处理多个连接。由于HTTP
请求不会太耗时,而且多个连接一般不会同时来消息,所以一个线程处理多个连接没有太大问题。
Thanks