对Java程序员来说,我们对面向对象的编程(OOP)自然都是烂熟于胸的,但语言也极大地影响了我们构建面向对象应用程序的方式。(现在的OOP已经和Alan Kay当初创造这个词时候的初衷大不相同了,他的主要思想是采用消息传递并消灭所有状态数据(他认为,系统是由一些类似于生物细胞那样的对象构成的,这些对象通过消息传递进行通信,且无需持有任何状态)——go语言)

对于Java程序员来说,当我们顺着指针或引用找到某个实例的时候,实际上是登录到了持有其状态的一块内存上,于是在那个位置上操纵数据也就成了自然而然的事了。该位置即代表了对象实例及其所包含的数据。将实体与状态进行合并最初看起来是非常简单且易于理解的,但从并发的角度来看,这种做法其实有很多严重的不良后果。例如,如果我们需要实现一个打印银行账户详情(资金数量、当前余额、交易信息、最小余额等等)的程序,我们就会碰到很多并发相关的问题。你会发现手头待处理的引用其实是一个随时都可能发生变化的状态的代理。所以当我们查看账户信息的时候,就需要通过加锁来阻止其他线程对账户内容进行修改,而这也必将导致并发度的大幅下降。但问题并不是从加锁的那一刻才开始出现的,而是在我们把账户的实体与其状态合并的时候就已经存在了。

我们曾经被告知说面向对象的编程是对真实世界的建模。但悲催的是,真实世界与OO范式所试图构建的模型实际是大相径庭的。因为在真实的世界中,状态是不变的,而实体却是不断变化的。接下来我们将讨论这种说法为何是正确的。

将实体与状态分离

你能快速告诉我Google的股价现在是多少吗?我们当然可以说从证券市场开市的那一刻起股价就是在不断变化的。举一个简单的例子,2010年12月10日Google的收盘价是592美元,并且这个数字已经被载入史册、是不会再改变了。当然,Google今天的股价和那天已经完全不同了。而如果过几分钟之后再来查看Google的股价(假设证券市场是开市的),我们就会看到一个不一样的值,但之前的那个值其实并没有改变。从现在开始,我们得改变一下我们对对象的认识,而这也将同时改变我们使用对象的方式。后面我们会看到,把对象的实体与其不可变状态值进行分离的做法将如何帮助我们实现锁无关编程、提高并发度、同时最大程度地降低竞争。

将实体与状态分离绝对是一个天才的构想,这是STM模型过程中所采用的一个非常关键的步骤。假定我们的Google股票对象由两部分组成:第一部分用于表示该股的实体,其中包含一个指向第二部分的指针。第二部分则包含了该股最新股价,其中保存股价的变量即为不可变状态,如图 1所示。

 

图 1 将可变实体部分与不可变状态值进行分离

一旦接收到一个新的股价信息,我们就可以将其放入历史价格指数中。由于旧的股价是不可变的,所以我们可以将其共享出去供所有线程访问。Google股票对象就可以多快好省地对外提供数据读取服务。而一旦有新的数据准备就绪之后,我们可以快速更改实体中的指针,以使其指向保存新股价的字段。实体与状态分离的做法对于并发来说也是一大福音。因为采用了这种方法之后,我们就可以不用阻塞任何查询股价的请求了。由于状态是不会变的,所以我们可以欣然将其指针传递给发出查询请求的线程。

STM中的事务

事务的概念源自于数据库管理系统(DBMS)中数据库事务的概念。在数据库管理系统中,事务必须满足ACID性质,即原子性,一致性,隔离性和持久性。原子性指的是事务中的动作要么全部执行,要么一个都不执行;一致性指的是任何时刻,数据库必须处于一致性状态,即必须满足某些预先设定的条件;隔离性是指一个事务不能看见其他未提交事务所涉及到的内部对象的状态,而持久性则是指一个已提交的事务对数据库系统的改变必须是永久的。由于STM中的数据是全都放在内存而不是数据库或文件系统里的,所以STM只提供了事务的前三个属性,而缺少了对持久性的支持。通过将对内存的访问封装在事务(transactions)中,STM消除了多线程内存同步过程中我们易犯的那些错误!

在Clojure语言中,STM实现采用了与数据库相似的多版本并发控制技术(MVCC),其并发控制也和数据库中的乐观锁(optimistic locking)很像。当我们启动一个事务的时候,STM会记录一下时间戳,并将事务中将会用到所有ref都拷贝一份。由于状态是不可变的,所以对于ref的拷贝是多快好省的。当对某个不可变状态进行“变更”的时候,我们其实并没有改变它的值(value),而是为其创建了一个含有新值的拷贝。该拷贝是本事务的一个内部状态,并且由于我们使用了持久化的数据结构,这一步也是多快好省的。而如果STM识别出我们操作过的ref已经被别的事务改了的话,它就会中止并重做本事务。当事务成功完成时,所有的变更都会被写入内存,而时间戳也将被更新!

STM中的事务实现

软件事务内存的实现包括原子对象(Atomic object)、冲突判决器(Conflict manager)。其中原子对象的实现是最重要的,它是各事务之间通信同步的媒介。原子对象的实现又分为顺序性实现和事务实现:其中事务实现还要要求实现同步和恢复(recovery)功能,同步功能即意味着要求有检测事务冲突的能力,而恢复功能则意味着需要在事务失败的时候将对象回滚到事务执行之前的状态。目前提出的原子对象一般是基于读/写冲突(Read/Write conflict)的机制:原子对象提供两个接口,一个为读接口,一个为写接口,通过读接口可以得到一个可以读的对象,而通过写接口则可以得到一个可以写的对象。为了检测冲突(即多个事务并发时的同步情况),事务中可以设立两个集合,一个为读集(Read set),一个为写集(Write set),分别记录该事务所要处理的读写原子对象集。如果一个事务的读集或写集与另一个事务的写集有交叉,则表明两个事务冲突,需要冲突判决器进一步采取决策。

总结:STM 软件事务内存——本质是为提高并发,通过事务来管理内存的读写访问以避免锁的使用!对于clojure,akka来说,只需将对事务内存的操作封装为事务,简化了并发编程而让程序员无需考虑复杂的事务同步问题!

转载于:https://www.cnblogs.com/bonelee/p/6056311.html

STM 软件事务内存——本质是为提高并发,通过事务来管理内存的读写访问以避免锁的使用...相关推荐

  1. C++ 以智能指针管理内存资源

    1.简介 C++ 作为一门应用广泛的高级编程语言,却没有像 Java.C# 等语言拥有垃圾回收(Garbage Collection )机制来自动进行内存管理,这也是C++ 一直被诟病的一点.C++ ...

  2. LwIP 之五 详解动态内存管理 内存堆(mem.c/h)

    写在前面   目前网上有很多介绍LwIP内存的文章,但是绝大多数都不够详细,甚至很多介绍都是错误的!无论是代码的说明还是给出的图例,都欠佳!下面就从源代码,到图例详细进行说明.   目前,网络上多数文 ...

  3. Android之内存管理-内存监测-内存优化

    推荐文章:Android进程与内存及内存泄漏 Android之内存管理 1.1 Dalvik Dalvik虚拟机是Android程序的虚拟机,是Android中Java程序的运行基础.其指令集基于寄存 ...

  4. 深入浅出事务的本质,附 OceanBase 事务解析14问

    作者:颜然,蚂蚁集团资深技术专家 OceanBase 初创成员之一,OceanBase 分布式数据库事务研发负责人,目前负责事务引擎.高可用架构.负载均衡.性能优化等方面的工作. 事务的前世 每个人的 ...

  5. 你真的了解软件开发的本质吗?

    摘要:我们总是喜欢用自己的经历来定义软件是什么以及判断标准,但如果这种经历来自完全不同的两个领域,并且互相矛盾,那么就有可能让大家吵来吵去--是的,各位在忙于解决具体问题时,谁还会想到谈谈软件开发的本 ...

  6. 软件隐喻的本质与模式

    1.引言 隐喻思维具有普遍性,是人类认知得以深化的前提之一,隐喻是丰富人类语言的有效手段. 然而,一直以来,对于隐喻的讨论主要限于语言学和修辞学,从而将隐喻狭隘化,局限化,使得隐喻在其他领域中的作用未 ...

  7. C#(Net)软件开发常用工具汇总,提高你的开发效率

    C#(Net)软件开发常用工具汇总,提高你的开发效率 写代码也要读书,爱全栈,更爱生活.每日更新原创IT编程技术及日常实用技术文章. 我们的目标是:玩得转服务器Web开发,搞得懂移动端,电脑客户端更是 ...

  8. 3.软件开发的本质和基本手段

    3.1 软件开发的含义 正确认识软件开发,是从事软件开发的思想基础. 软件开发的本质: 不同抽象层术语之间的"映射" 不同抽象层处理逻辑之间的"映射" 3.2 ...

  9. 【选摘】如何提高月结事务的性能

    如何提高月结事务的性能 -内容整理转自<由浅入深学习SAP财务> 某些企业在使用SAP 多年之后会发现系统的性能差,主要体现在月结的某些步骤执行起来会越来越慢,比如生产订单结算" ...

最新文章

  1. 参加完Python培训可以做什么
  2. SQL与NoSQL区别-查询方式
  3. Ghost配置1——删除社交Link
  4. 软考可以一次报两门吗
  5. 编程方法学15:指针要点回顾
  6. Moodle网站档案的结构
  7. 【华为云技术分享】【DevCloud · 敏捷智库】如何利用核心概念解决估算常见问题
  8. androidstudio自带git用法_Android Studio的git功能的使用介绍
  9. Catia二次开发:数组,局部变量等,msgbox,背景颜色,enable属性,图片模块,vb的common dialog控件,键盘鼠标事件,text操作
  10. kappa一致性检验教程_一致性检验的几种方式--ICC、kappa、weighted kappa、Kendall
  11. 初中数学抽象教学的案例_初中数学教学案例与反思
  12. SEO优化基础知识大全 SEO新手入门必备知识
  13. jdk8中新增的日期处理类LocalDate,LocalTime,LocalDateTime,ZoneId,ZonedDateTime详解
  14. 如何分析数据建立数据表
  15. 3199. 命令行选项
  16. 小白自学Java后端学习计划(附带学习视频)
  17. 微信公众号发布投票教程
  18. 电脑修改用户(User)文件夹名称
  19. 不眠的硅谷——Just For Fun
  20. 微信tinker导致冷启动变慢的问题优化

热门文章

  1. php curl异步跳转,php curl批处理--可控并发异步
  2. mongodb spring 超时时间_spring data mongodb 配置遇到的几个问题
  3. delphi usb 通信_意法半导体推出集成共模滤波器和ESD抑制功能的新汽车通信保护器件...
  4. css规则由两部分构成,CSS-层叠样式表基础教程
  5. Java程序员校招蚂蚁金服,mysql培训考试
  6. 链表的排序(Python和C实现)
  7. 机器学习(MACHINE LEARNING)MATLAB模拟退火算法【SA】
  8. 机器学习(MACHINE LEARNING) 【周志华版-”西瓜书“-笔记】 DAY15-规则学习
  9. 免费使用谷歌GPU训练神经网络
  10. mysql test 映射到实体_MyBatis实体关系映射