什么是原子操作?如何实现原子操作?
假定有两个操作A和B,如果从执行A的线程来看,当另一个线程执行B时, 要么将B全部执行完,要么完全不执行B,那么A和B对彼此来说是原子的。
实现原子操作可以使用锁,锁机制,满足基本的需求是没有问题的了,但是 有的时候我们的需求并非这么简单,我们需要更有效,更加灵活的机制,synchronized关键字是基于阻塞的锁机制,也就是说当一个线程拥有锁的时候, 访问同一资源的其它线程需要等待,直到该线程释放锁,这里会有些问题:首先,如果被阻塞的线程优先级很高很重要怎么办?其次, 如果获得锁的线程一直不释放锁怎么办?(这种情况是非常糟糕的)。还有一种 情况,如果有大量的线程来竞争资源,那CPU将会花费大量的时间和资源来处 理这些竞争,同时,还有可能出现一些例如死锁之类的情况,最后,其实锁机制 是一种比较粗糙,粒度比较大的机制,相对于像计数器这样的需求有点儿过于笨 重。
实现原子操作还可以使用当前的处理器基本都支持CAS()的指令,只不过每 个厂家所实现的算法并不一样,每一个CAS操作过程都包含三个运算符:一个内 存地址V,一个期望的值A和一个新值B,操作的时候如果这个地址上存放的值 等于这个期望的值A,则将地址上的值赋为新值B,否则不做任何操作。
CAS的基本思路就是,如果这个地址上的值和期望的值相等,则给其赋予新 值,否则不做任何事儿,但是要返回原值是多少。循环CAS就是在一个循环里不 断的做cas操作,直到成功为止。
CAS是怎么实现线程的安全呢?语言层面不做处理,我们将其交给硬件—CPU和内存,利用CPU的多处理能力,实现硬件层面的阻塞,再加上volatile变 量的特性即可实现基于原子操作的线程安全。