所谓同步,指的是协同步调。
既然叫协同所以至少要有2个以上的事物存在。协同的结果就是多个事物不能同时进行必须一个一个的来上一个事物结束后下一个事物才开始。那当一个事物正在进行时其它事物都在干嘛呢严格来讲这个并没有要求但一般都是处于一种“等待”的状态因为通常后面事物的正常进行都需要依赖前面事物的结果或前面事物正在使用的资源。因此可以认为同步更希望关注的是从宏观整体来看多个事物是一种逐个逐个的串行化关系绝对不会出现交叉的情况。所以自然也不太会去关注某个瞬间某个具体事物是处于一个什么状态。把这个理论应用的出神入化的非“排队”莫属。凡是在资源少需求多的场景下都会用到排队。比如排队买火车票这件事其实售票大厅更在意的是旅客一个一个的到窗口去买票因为一次只能卖一张票。即使大家一窝蜂的都围上去还是一次只能卖一张票何必呢挤在一起又不安全。只是有些人素质太差非要往上挤售票大厅迫不得已采用排队这种形式来达到自己的目的即一个一个的买票。至于每个旅客排队时的状态是看手机呀还是说话呀根本不用去在意。除了这种由于资源导致的同步外还存在一种由于逻辑上的先后顺序导致的同步。比如先更新代码然后再编译接着再打包。这些操作由于后一步要使用上一步的结果所以只能按照这种顺序一个一个的执行。关于同步还需知道两个小的点一是范围并不需要在全局范围内都去同步只需要在某些关键的点执行同步即可。比如食堂只有一个卖饭窗口肯定是同步的一个人买完下一个人再买。但吃饭的时候也是一个人吃完下一个人才开始吃吗当然不是啦。二是粒度并不是只有大粒度的事物才有同步小粒度的事物也有同步。只不过小粒度的事物同步通常是天然支持的而大粒度的事物同步往往需要手工处理。比如两个线程的同步就需要手工处理但一个线程里的两个语句天然就是同步的。所谓异步就是步调各异。既然是各异那就是都不相同。所以结果就是多个事物可以你进行你的、我进行我的谁都不用管谁所有的事物都在同时进行中。一言以蔽之同步就是多个事物不能同时开工异步就是多个事物可以同时开工。注一定要去体会“多个事物”多个线程是多个事物多个方法是多个事物多个语句是多个事物多个CPU指令是多个事物。等等等等。阻塞和非阻塞所谓阻塞指的是阻碍堵塞。它的本意可以理解为由于遇到了障碍而造成的动弹不得。所谓非阻塞自然是和阻塞相对可以理解为由于没有遇到障碍而继续畅通无阻。对这两个词最好的诠释就是当今中国一大交通难题堵车汽车可以正常通行时就是非阻塞。一旦堵上了全部趴窝一动不动就是阻塞。因此阻塞关注的是不能动非阻塞关注的是可以动。不能动的结果就是只能等待可以动的结果就是继续前行。因此和阻塞搭配的词一定是等待和非阻塞搭配的词一定是进行。回到程序里阻塞同样意味着停下来等待非阻塞表明可以继续向下执行。阻塞和等待等待只是阻塞的一个副作用而已表明随着时间的流逝没有任何有意义的事物发生或进行。阻塞的真正含义是你关心的事物由于某些原因无法继续进行因此让你等待。但没必要干等你可以做一些其它无关的事物因为这并不影响你对相关事物的等待。在堵车时你可以干等。也可以玩手机、和别人聊天或者打牌、甚至先去吃饭都行。因为这些事物并不影响你对堵车的等待。不过你的车必须呆在原地。在计算机里是没有人这么灵活的一般在阻塞时选在干等因为这最容易实现只需要挂起线程让出CPU即可。在条件满足时会重新调度该线程。两两组合所谓同步/异步关注的是能不能同时开工。所谓阻塞/非阻塞关注的是能不能动。通过推理进行组合同步阻塞不能同时开工也不能动。只有一条小道一次只能过一辆车可悲的是还TMD的堵上了。同步非阻塞不能同时开工但可以动。只有一条小道一次只能过一辆车幸运的是可以正常通行。异步阻塞可以同时开工但不可以动。有多条路每条路都可以跑车可气的是全都TMD的堵上了。异步非阻塞可以工时开工也可以动。有多条路每条路都可以跑车很爽的是全都可以正常通行。是不是很容易理解啊。其实它们的关注点是不同的只要搞明白了这点组合起来也不是事儿。回到程序里把它们和线程关联起来同步阻塞相当于一个线程在等待。同步非阻塞相当于一个线程在正常运行。异步阻塞相当于多个线程都在等待。异步非阻塞相当于多个线程都在正常运行。I/OIO指的就是读入/写出数据的过程和等待读入/写出数据的过程。一旦拿到数据后就变成了数据操作了就不是IO了。拿网络IO来说等待的过程就是数据从网络到网卡再到内核空间。读写的过程就是内核空间和用户空间的相互拷贝。所以IO就包括两个过程一个是等待数据的过程一个是读写拷贝数据的过程。而且还要明白一定不能包括操作数据的过程。阻塞IO和非阻塞IO应用程序都是运行在用户空间的所以它们能操作的数据也都在用户空间。按照这样子来理解只要数据没有到达用户空间用户线程就操作不了。如果此时用户线程已经参与那它一定会被阻塞在IO上。这就是常说的阻塞IO。用户线程被阻塞在等待数据上或拷贝数据上。非阻塞IO就是用户线程不参与以上两个过程即数据已经拷贝到用户空间后才去通知用户线程一上来就可以直接操作数据了。用户线程没有因为IO的事情出现阻塞这就是常说的非阻塞IO。同步IO和同步阻塞IO按照上文中对同步的理解同步IO是指发起IO请求后必须拿到IO的数据才可以继续执行。按照程序的表现形式又分为两种在等待数据的过程中和拷贝数据的过程中线程都在阻塞这就是同步阻塞IO。在等待数据的过程中线程采用死循环式轮询在拷贝数据的过程中线程在阻塞这其实还是同步阻塞IO。网上很多文章把第二种归为同步非阻塞IO这肯定是错误的它一定是阻塞IO因为拷贝数据的过程线程是阻塞的。严格来讲在IO的概念上同步和非阻塞是不可能搭配的因为它们是一对相悖的概念。同步IO意味着必须拿到IO的数据才可以继续执行。因为后续操作依赖IO数据所以它必须是阻塞的。