来源:https://www.jianshu.com/p/62c0cd107da3

同步和异步、阻塞和非阻塞

首先要明确的是,同步(Synchronous)和异步(Asynchronous),阻塞(Blocking)和非阻塞(Non-Blocking)是两种完全不同的概念。前者指的是一种事件通知、处理机制,而后者则是程序控制流程的差异。

我们以A调用B为例来说明两者之间的区别:

  • 阻塞
    只有当B任务完成后,程序控制权才会返回给A, A得以继续执行。

  • 非阻塞
    B马上返回,此时B并没有完成,但A可以继续执行,B任务并不影响
    A的执行。

  • 同步
    A需要通过某种方式主动查询B是否完成。在blocking模式中,它表现为等待B返回;在non-blocking模式中表现为通过Future对象询问B是否完成,如果完成则取出结果,未完成则等待(阻塞)。

  • 异步
    A在启动B任务时就不管了,继续执行自己的任务,当B完成时,由操作系统主动通知A,告知B已经完成。A可以在适宜的时候取出B的执行结果。在这种模式下,A完全不会因为B的执行而影响自己。

异步是解决web应用高并发的唯一方案

“传统的”一线程对一请求的模型直接决定了单机并不能处理过多的并发请求,而且这种模型下会导致很大的线程资源浪费。这里面原因有二:一是每条线程占用要使用较多的内存,在JVM中每创建一个线程就要消耗2M多的heap,于是内存大小就变成线程数量的瓶颈;二是当线程数据超过CPU核心数时,频繁的线程切换会变成一笔可观的开销,而且当你的程序因为查询数据库、执行RPC调用阻塞当前线程时,这个线程是完全不能运行的,不仅白白占用了内存,还增加了Context Switch的次数。

异步并不能加快你对于单个请求的处理速度,但是它能最大化的消灭资源浪费,从而大大提高单机并发极限。

Go的世界中,万物皆异步

Go中只有协程,而协程本质上就是异步。

为什么这么说呢?首先我们知道,协程(routine)跟线程是多对一的关系,routine本身不会被调度执行,它只能依靠操作系统的线程来运行。一个线程可以执行多个routine, Go运行时调度器负责进行调度处理。routine只有三种情况需要让出执行权,分别是system call, 锁竞争和主动让出执行权力。

  • system call
    当发生系统调用时,执行当前routine的线程会block这是没得商量的,但go运行时会从它维护的线程池中取出一条空闲线程继续执行其它routine, 这样就做到了即使你block了routine,也不会影响其它routine的执行。这里可以类比于Netty中的I/O线程,如果你代码block了,则会卡住其他任务的执行,否则你必须在自己的线程池中执行会产生block的代码。

  • 网络I/O
    调用net包下的网络I/O操作是不会阻塞线程的。当发起网络I/O请求时,go运行时会通过操作系统提供的epoll机制注册I/O事件,不会挂起实际干活的线程,只会切换goroutine而已。

  • 竞争
    无论是锁竞争还是读写channel而导致routine被挂起,其背后的线程都是不会有任何block的,在OS看来线程一直在正常运行,从而大大降低了线程上下文切换的开销。

  • 主动让出执行权
    同上面的竞争,主动让出执行权时背后的线程同样不会block。

仔细想想看,这跟前面讲的异步不是几乎一样的逻辑吗?区别是,Go语言中是Go自己的调度器来通知routine等待的IO事件是否完成,而其它非协程语言则是OS来通知。

因此,Go中我们虽然在以同步的方式编写代码,但却与异步有着异曲同工之妙。

最新文章

  1. PHP之几道面试题
  2. 使用css3新属性clip-path制作小图标
  3. Sql Server Job 简单使用
  4. 使用proguard混淆java web项目代码
  5. c# 类型拷贝
  6. rsync的断点续传设置。
  7. log4net 总结
  8. Android 有趣味的GridView
  9. 求n个数的最小公倍数
  10. Nginx浅谈
  11. WC2019 游记
  12. rabbit初学之连接测试2
  13. MFC为多个控件绑定同一个函数
  14. ServiceFramework作为Java Web框架都有哪些不错的设计
  15. SQL GROUP BY对多个字段进行分组
  16. golang配置
  17. Springboot+JdbcTemplate +thymeleaf 页面 做迷你版的bug系统
  18. RMQ 解决区间查询问题
  19. css 控制文字超出时显示省略号
  20. C# Visual 快捷键

热门文章

  1. 思考设计SQL优化方案
  2. coderforces Gym 100803A/Aizu 1345/CSU 1536/UVALive 6832 Bit String Reordering(贪心证明缺)
  3. D - D 分糖果HDU - 1059(完全背包+二进制优化)
  4. java 第六周上机练习 04.09
  5. PTA数据结构与算法题目集(中文) 7-18
  6. VMwareWorkstation如何设置共享文件夹
  7. 2017蓝桥杯算式900(C++C组)
  8. 实时OLAP分析利器Druid介绍
  9. k8s中token过期重新生成
  10. 一个不错的spring 学习博客