[JAVA学习笔记-75]关于CAS

Compare and swap
CAS即比较并交换,目前处理器在指令集中予以支持。换句话说,对于应用程序开发来说,并不直接使用CAS方法,而是使用特定的接口来使用。
以JAVA为例,CAS被封装在原子对象中,如AtomicInteger,如果调用其incrementAndGet()方法,则方法内部通过unsafe调用底层操作系统+汇编
指令执行CAS。
还是以JAVA为例,AtomicXXX族的引入避免了在对primitive types进行增减操作时需要用到synchronized,reentrantLock等重型的同步方式,而
volatile本身无法保证原子性(volatile只能保证多线程可见性,但是对volatile变量的运算操作,非原子操作,如i++)

//使用volatile
public class MyApp
{
private volatile int count = 0;
public void upateVisitors()
{
++count; //increment the visitors count
}
}

//使用常规同步(对象锁)
public class MyApp
{
private int count = 0;
public synchronized void upateVisitors()
{
++count; //increment the visitors count
}
}

//使用AtomicInteger
public class MyApp
{
private AtomicInteger count = new AtomicInteger(0);
public void upateVisitors()
{
count.incrementAndGet(); //increment the visitors count
}
}

public final long incrementAndGet() {
for (;;) {
long current = get();
long next = current + 1;
if (compareAndSet(current, next))
return next;
}
}

适用性:
Using synchronised is more efficient if you expect to be waiting a long time (e.g. milli-seconds) as the thread can fall asleep and release the CPU to do other work.
【synchronised使用方便,如果线程等待时间较长,使用这种方式更好。】

Using compareAndSwap is more efficient if you expect the operation to happen quite quickly. This is because it is a simple machine code instruction and take as little as 10 ns. However if a resources is heavily contented this instruction must busy wait and if it cannot obtain the value it needs, it can consume the CPU busily until it does.
【如果同步操作非常短小(时间短,代码规模小),则适合用CAS机制的AtomicXXX族对象。但是如果资源争夺较激烈,可能造成CPU资源浪费(CAS的本质
是循环比较并等待,如果一个线程长时间获取不到目标对象,会一直循环比较。而对象锁的方式线程可以sleep释放CPU。)
简述:
传统对象锁的同步方式适合体量比较大,同步效率要求不是特别高的场景;CAS适合同步操作短小精悍,但资源竞争不是特别激烈的场景。】

If you use off heap memory, you can control the layout of the data being shared and avoid false sharing (where the same cache line is being updated by more than one CPU). This is important when you have multiple values you might want to update independently. e.g. for a ring buffer.

Note: synchronized is implemented using a compareAndSwap and much more besides and has to do work on obtaining the lock and releasing it.

注:
1、AtomicInteger的set方法,直接对value赋值,因为value是volatile变量,所以自动保证多线程的可见性。
2、Set方法与getAndSet为什么在实现上有区别,后者为什么要用compareAndSet而不是直接赋值?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值