Monad、Actor与并发编程--基于线程与基于事件的并发编程之争
将线程、事件、状态等包装成流的源。
核心:解决线程的消耗和锁的效率问题。
Java和Node.js可以说分别是基于线程和基于事件的两个并发编程代表,它们互相指责瞧不起对方,让我们看看各种阵营的声音:
基于事件的粉丝认为线程是一个坏主意,原因有是:
1. 你得显式的协调共享数据的锁,如果你忘记加锁,你就会得到中断坏的数据。
2. 依赖锁导致死锁。
3. 它们难以调试
4. 回调并没有锁
5. 多线程在多核上的性能并不会比每个单核一个线程性能更好。
你应当尽可能地避免线程,对于GUI和分布式系统或低端服务器不要用线程,只有处理CPU并发时才需要线程,如果必须使用线程,将线程隔离在核心内部,让大部分代码保持单线程。
而基于线程的粉丝认为Why events are a bad idea,反驳理由是:
1. 很多使用线程实现高并发却没有获得好性能?这其实假象,有人创建一个可扩展到100,000的线程库,其性能匹配SEDA的基于事件实现的性能。
2.线程限制流程控制?线程派分析了基于事件的系统, 发现这些应用控制流程模式有三种:call-return, parallel calls和 pipeline. 这些都很容易使用线程表达。
3.线程同步锁太重量?协调式多任务(协程)能让线程轻量等同于基于事件的并发。
4.线程堆栈没有足够效率管理活动状态?不是,一个新的动态增长性堆栈stack模型可以解决这个问题。
5.线程会阻止运行时刻进行优化调度决定?不是这样,Lauer 和Needham 都显示不是这种情况。
线程派认为现代服务器虽然需要并发处理大量的请求,但是代码处理每个请求通常是有顺序的,我们相信线程提供这两种情况下很好的编程抽象。
尽管事件系统在高并发下有很好的性能,但是我们已经证明使用线程也会有类似性能(banq注:不过真的需要高手),由于语言提供编译时的分析使得线程简单,一样和基于事件系统能实现高并发。
线程派的改良代表可以首推Go的Goroutine和Python的coroutine协程,它们解决了直接基于OS线程导致线程上下文切换时带来的性能损耗,而且通过调度器保证非堵塞。Goroutine最大的特点能够让程序员以同步顺序代码的风格编写异步运行,Goroutine=coroutine协程 + user space threads + fibers + greenlets。因为绿色线程被封装在语言的API中,因此相比Node.JS显式处理异步IO,GO语言提供了隐式的异步处理IO,从而使得并发异步变得简单。
在GO语言的竞争之下,Node.JS一直探索如何避免回调陷阱,从Promise 到coroutine/Generators,直至演化到Javascript 7的async函数。从而也可以实现使用熟悉的顺序编程风格编写出异步代码,下面是使用JS 7的新的异步函数:
function* getStockPrice(name) { |
Javascript 7主要亮点是在事件机制和异步编程的提升上,这两点主要体现在:
1. Object.observe使得模型和视图之间很容易同步。
2. async函数更易于异步编程,能够实现拉Pull或推Push。
http://www.jdon.com/idea/js/javascript7.html
以Node.js为主的事件派和Go的协程派打得热乎时,这时有了一种观点,既然你们两者都回避各自缺陷表现得不错,下面是就剩下使用者的爱好和技能选择了,能不能提供一种语言将这两者结合在一起?
Haskell倡导者提出通过语言统一多线程编程和事件编程,提供一种Monad函数,其内部封装了事件和多线程抽象,无论你是哪派粉丝,都可以使用这个Monad编程。如下图:A language-based approach to unifying events and threads
这种观点得到大多数人的同意,这时被冷落一边的Scala的Actor模型站出来认为自己的Actor函数属于这种两者合一的Monad函数,见这里
当然,Go的绿色线程Goroutine与Actor还是有区别的:Actor模型和CSP模型的区别
纵观并发编程发展,大家都是从IO这个串行化端口入手,神仙过海,各显神招,从当初Java的NIO 到Node.JS的异步IO 再到Go的Goroutine以及Netty 以及Actor模型等等,应该说,谁在Socket IO这个战场上性能和易用性表现得更好,谁就可能在并发编程整个领域获得全胜。
https://www.jdon.com/46921
Monad、Actor与并发编程--基于线程与基于事件的并发编程之争的更多相关文章
- 并发编程 13—— 线程池的使用 之 配置ThreadPoolExecutor 和 饱和策略
Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...
- Scala 深入浅出实战经典 第68讲:Scala并发编程原生线程Actor、Cass Class下的消息传递和偏函数实战解析
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...
- Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- Java并发编程:线程池的使用(转)
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- Java并发编程:线程池的使用(转载)
转载自:https://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...
- Java并发编程:线程池的使用(转载)
文章出处:http://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...
- [转]Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- 【转】Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- 13、Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
随机推荐
- new~mac os 给终端命令写alias(及其他常用命令)及软连接
配置执行顺序 优先级 配置 说明 1 /etc/profile 系统级别 —— 不推荐修改 2 /etc/paths 系统级别 —— 不推荐修改 3 ~/.profile 用户设置 4 ~/.bash ...
- MyCAT全局序列号-数据库方式
1.MyCat中的全局序列号介绍 在实现分库分表的情况下,数据库自增主键已无法保证自增主键的全局唯一.为此,MyCat 提供了全局 sequence,并且提供了包含本地配置和数据库配置等多种实现方式. ...
- Java基础——Servlet(六)分页相关
前面写了Servlet(一)到(五),主要是在网上搜罗的视频.对分页这块还是不太清楚.于是有找到一些视频,重新学习了一下.主要是对分页的认识和设计思路.也是为了方便我以后回忆一下.. 一.分页常识 p ...
- Java基础——反射
今天学到Java基础中的反反射.依照我学习后的个人理解呢,反射就是一套获取类.属性.方法等的工具吧.(其实,感觉学完反射后,有点像喝凉水,解渴但确实我也没体会出它有什么味道,我可能没有学到精髓吧.自己 ...
- 不要62(hdu2089)
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...
- css优化,提高性能
CSS 优化主要是四个方面: 加载性能比如不要用 @import 等等,@import会影响css文件的加载速度,考虑加载性能时,主要是从减少文件体积.减少阻塞加载.提高并发方面入手,任何 hint ...
- Console控制台的正确打开方式
Console控制台的正确打开方式 console对象提供了访问浏览器调试模式的信息到控制台 -- Console对象 |-- assert() 如果第一个参数断言为false,则在控制台输出错误信息 ...
- js-ES6学习笔记-字符串的扩展
1.codePointAt方法是测试一个字符由两个字节还是由四个字节组成的最简单方法.codePointAt方法会正确返回32位的UTF-16字符的码点. function is32Bit(c) { ...
- 【读书笔记】iOS-网络-优化请求性能
一,度量网络性能 1,网络带宽 用于描述无线网络性能的最常见度量指标就是带宽.在数字无线通信中,网络带宽可以描述为两个端点之间的通信通道每秒钟可以传输的位数.现代无线网络所能提供的理论带宽是很高的.不 ...
- js相关判断
//正则表达式判断是否为空 /^\s*?$/.test(obj) //批量转换方法 function sort(s){return s.match(/\d/g).sort()+'' } //判断是否相 ...