网络Io,发送一次网络请求一般1毫秒到几百毫秒。 磁盘io,一般5毫秒到几百毫秒。两种io每次时间都不固定,即使是取相同的数据。网络Io可能有网络波动导致。
io密集型。cpu不断的发起请求,每次都需要等待几十或几百毫秒。拿到数据后处理速度又是1微妙就解决了。所以大部分时间cpu都在打空转。
本地磁盘转一圈大约5毫秒,如果取的数据比较大,就转很多圈。时间就又很多。
以前cpu从内存取数据都是20纳秒,现在都提升到毫秒级。时间百万倍增长。
怎么提高cpu的利用率,比如网络请求大量数据,1万份。然后创建100个线程,当第一个线程发出请求后,切换线程。其他线程开始依次发送请求。线程不要开的多了。线程切换需要1豪秒,也是要花费时间的,而且切换时cpu也不会工作,线程也会增加内存开销。 创建线程一般考虑cpu的核数,cpu任务执行时间和浪费时间比。这个数越大,需要开的线程越少。又因为线程切换的时间,所以最终结果还是要测试出来。
10万个数据,开100个线程,每个线程1000个任务。有的线程快,有的线程慢。快的线程完成任务后就被销毁了。最后任务还有很多,线程数减少了。相当于cpu性能又降低了。所以这样分配线程有缺陷。
咱们想要的是线程一直存在,然后这样效率就不会低了。可以这样做,就是不把任务平均分配了,每个线程每次处理一个任务,当处理完后,就去这10万个数据里拿任务。直到任务被处理完。每个线程的判断条件就是这10万个数据是否为空,当数据为空了就销毁线程。正好就用到了线程池。线程池帮咱们管理这些线程。
线程池一般使用有界队列,这样才能触发线程扩容。然后线程池在没有任务时线程个数是0,当处理一个任务时,数量变成了核心线程数,当把任务处理完了,也不会降到0,也是降到了核心线程数。 然后就是线程池那一套了。
对时间没有要求的可以使用无界队列。比如网络爬虫,数据处理