并发与并行
并发很好的利用了CPU时间片的特性,就是操作系统选择并运行一个任务,接着在下一时间片内运行另一个任务,并把前一个任务设置成等待状态。但并发并不代表并行。
比如以下几种情况:
- 有时候多线程执行会提高应用程序性能,而有时候反而会降低性能。这在JDK中的Stream API的使用上体现得很明显,如果任务量很小,而我们使用了并行流,反而降低了程序性能。
- 在多线程编程中,可能会同时开启或关闭多个线程,这样会产生很大的性能开销,也降低了应用程序的性能。
- 当线程同时处于等待I/O的过程中时,并发可能会阻塞CPU资源,其后果不仅是用户长时间等待,而且会浪费CPU的计算资源。
- 如果几个线程共享了一个数据,需要考虑数据在各个线程中的状态是否一致。很可能会使用synchronized或者lock相关操作。
并发很好,但并不一定会实现并行。并行是在多核CPU上同一时间运行多个任务或者一个任务分为多块同时执行(如ForkJoin)。单核CPU的话,就不考虑并行了。
实际上多线程就意味着并发,但是并行只发生在这些线程在同一时间调度,分配到不同CPU上执行的情况下。
强调一下,线程只是一个对象,不是CPU执行核心,CPU时间片会切换执行这些线程。
响应式中的背压
在程序中,数据在从上游生产者向下游消费者传递过程中,若生产者速度大于消费者消费速度,那么可以将下游想象成一个容器,它处理不了这么多数据,然后数据就会从容器中溢出,那解决溢出问题的解决方案就被称为背压机制。
背压机制应该具有承载元素的能力,也就是它必须是一个容器,并且存储的元素有先后顺序,这里使用队列就最合适了。背压机制仅起承载作用是不够的,正因为上游进行了承压,所以下游可以按需请求元素,也可以在中间根据实际情况进行限流,以此上下游共同实现了背压机制。
网友评论