STM vs CAS

学习了几天的clojure,接触比较多的一个名词,就是STM(software transactional memory),软件事务内存。

CAS

说stm之前,先说说跟STM比较相似的CAS

在多线程领域,并发控制一直是个大难题。使用互斥锁虽然可以隔离共享变量的访问,但是一个资源同时只能被一个线程占用的时候,并发性能就会急剧下降。在java中,ReadWriteLock读写分离锁,ReentrantLock增加锁的伸缩灵活性,都是种治标不治本的方式。

于是就诞生了基于乐观索概念,通过版本(标识号,version,多种形式)控制数据访问的的无锁并发。java中的CAS就是基于此原理。

STM

软件事务内存也是基于乐观锁的一种实现形式。说到事务,一般想到的就是数据库,而stm的事务内存,跟数据库中mvcc非常像。只不过stm是在内存中实现的而已。

它相比CAS有什么优点:

更灵活。当处理复杂逻辑时,简单对象肯定无法满足需求,java中需要借助于AtomicReference,通过对象的比较实现CAS,那么在编码的时候,就需要知道,哪些对象可能出现并发危险。STM却可以将复杂的函数逻辑放到事务中,不用关心哪些数据会出现冲突,这和数据库的理念类似。

但这里有几个问题,需要在以后的学习中去解答:

  • 因为是基于内存的版本实现,所以在高并发中,内存消耗会很高。数据库可以使用这种方式,因为数据库的并发连接本身就不会多,而且数据库是基于硬盘的存储,消耗高也是可以接受的。而stm如果在服务器中应用,在高并发模式下,会消耗大量的内存来处理事务了。 所以stm更适合cpu密集型的应用,比如Storm?
  • 既然STM这么强大,为什么java没有应用。做不到,不屑于做,还是发现有隐患而没有去做? 首先不可能是做不到,因为clojure也是基于jvm虚拟机的,干儿子都做得到,凭什么java这个亲儿子做不到。那么为什么java没有做呢?

慢慢研究吧。