很多人反映多线程很难学习,很复杂;另外一方面,新技术框架层出不穷,学习过程疲于奔命,效果和方向却很茫然。

这是因为多数多线程的文章都偏重于技术框架API,而没有说清楚整体框架和思路,没有全局观,本文偏重于全局概念和思路。

一,多线程问题只有两种模式:多线程竞争和多线程协作。

线程只是一种表象,线程的本质是任务,协作和竞争的对象是数据。因此根本的问题是:任务和数据之间的关系。

多个任务和数据之间有两种关系:竞争关系和协作关系。

任务有多种体现形式:进程,线程,协程……他们是不同重量级(资源锁定/占用)的任务实现方式。

进程是有CPU和内存占用的任务;线程是占用CPU但是没有单独内存资源的任务——在一些OS中,进程和线程是没有区别的;协程是没有用户态和内核态切换的任务,是纯粹的逻辑块,是没有任何IO消耗的纯粹被事件驱动的逻辑块。

在LINUX中,原生进程是可以通过管道进行通讯的,但是JAVA线程不可以。他们通讯的唯一方式就是数据和信号。

影响软体性能的几个瓶颈资源分别是

1,IO(既数据)2,线程依赖(即锁:线程对线程的依赖——本质还是对数据的依赖)

这两个因素会极大的影响(降低)系统的性能。全速的CPU逻辑运算速度是亿级别,千万级别的,涉及到IO和锁,就降低为*W级别了。

高性能软体必须考虑瓶颈资源的使用,必须满足以下三个原则

1,让瓶颈资源最大限度得到发挥2,不做无用的事情3,通过合理调度完成

二,在多线程竞争场景中,高性能的程序解决思路是无锁和弱化锁

尽量的无锁,细粒度锁,局部锁,短促锁……比如众所周知的ShareNothing架构,短事务,JUC包,读写分离……等,是这种思路的产物。

三,在多线程协作场景中,涉及到信号机制

1,线程锁模型

常见的是CountDown,Semphore等包,这其实是一种效率稍低的信号机制,因为它锁定线程本身

有没有无线程锁定的信号机制呢?

2,Actor模型就是这种思路的产物

Actor模型下有Vertx,akka等。他的线程是用完即释放的。极大的提升了线程资源的利用率,比线程锁模型有更大的并发处理能力

还有没有优化的空间呢?

有,12提升的是线程资源的利用率,还可以从IO上考虑

3,IO优化框架

Netty是一种IO线程框架,他的事件源是IO。它解决的问题是IO和线程速率不匹配下的资源利用率问题。

但是Netty弊病是依赖于IO,如果阻塞的事件源不是IO,那Netty提升不了效率

有没有不依赖于IO的事件线程机制呢?

这就是Actor模型。

Actor模型相比于12模型,他本质上分离了IO和任务块,他的任务调度依赖于纯粹的事件机制,而不是IO事件。akka/Vertx/MQ都可以归为此类(MQ消耗太高,传统观念上就不归为此类,但原理一致的)

那么这是否就是最高性能呢?

no,在操作系统层面,有可能一次任务切换回涉及到OS的用户态和内核态切换,由于OS的安全机制,会做数据拷贝。这也是极大的性能消耗。

消除OS层面线程上下文切换的消耗,这就是协程等框架的基本原理。

所以协程框架必须让业务系统告诉(协程)框架:阻塞点是什么,任务块是什么,这需要在逻辑书写层面引入一些标记来区分,告诉框架应该如何去调度。

4,CPU指令层面的优化

123措施基本已经考虑到机制了么?还没有,disruptor等框架还考虑对CPU底层指令进行冗余填充,以提升CPU层面的处理速度。

(disruptor的Ring结构是另外一个层面——锁优化——的问题,这里不赘述)

五,实际业务系统优化做法

但是,我们并不鼓励在业务代码中考虑性能优化问题。

理论上,软体系统本质上是一个函数f,是纯粹的逻辑块。它的速度是千万级的,是远远超过任何业务场景要求的。

导致软体系统性能降低的原因是

1,架构设计层面让IO和业务逻辑耦合2,让业务逻辑程序员关注了太多依赖,而没有做好合适的模型设计和框架设计3,引入了太多框架,中间件……这些所谓的高性能框架,他们无论性能多么高,都不可能高过CPU内核速度的。他们提升的是业务的弹性扩展能力和可用性冗余——这对于绝大多数公司99.99%都是镜花水月——设计良好的单机系统可以支撑100-10000的并发处理能力,远远在绝大多数公司的需求之上。

但是另外一方面,绝大多数公司真正需要的是业务系统的业务快速响应,灵活扩展能力——罕有架构师去考虑这真正是业务公司需要的问题。而把精力 都关注到不需要的性能上了。

再重复一遍:我们并不鼓励在业务系统中考虑性能优化问题。

多数的情况下,只要你不做无意义的是(参见高性能原则2)就好了。

同样的哲学下,请记得分散式架构设计第一原则,多线程第一原则,性能优化第一原则

1,不要分散式你的系统

2,不要多线程

3,不要性能优化

优秀的架构欢迎懒人,讨厌多事的人

推荐阅读:

相关文章