关于CAS与LOCK FREE(java lock synchronized)

最近又看到有人在搞LOCK FREE的东西,在群里问CAS是什么。
CAS在我的理解就是下面这段代码


{if( *pVal == oldVal )  { *pVal = newVal; return true;} return false;}

当然,CAS把这段代码做成了一个原子操作。

很多人看到这里,并不是十分理解,这个原子操作怎么去实现LOCK FREE。

一般CAS会封装成下面的形式

    bool cas32( int * pVal, int oldVal, int newVal );

pVal 表示要比较和替换数值的地址,oldVal表示期望的值,newVal表示希望替换成的值。在多线程中使用时,一般是下面这样。

     volitale  int myValue;
    ......

    while( !cas32( &myValue, myValue, myValue+1 ) ) {
        ....
    }

这是什么意思呢?
我们知道,在多线程里面,如果多个线程同时在写一个变量,并且不进行同步的时候,这个变量的值就会不准确。比如两个线程同时在对一个变量进行+1操作的时候,他们分别需要进行三个操作,读入变量值(到寄存器),值+1,写入变量值(到变量内存地址)。这三个操作是无法保证原子性的,也就无法保证变量在读入,+1后,原变量没有被别的线程修改。
cas在这里做的实际上就是在变量没有被其他线程修改,或者被修改但是又恢复到我们期望读入的值的时候,修改变量的值。这句话很拗口,其实看CAS的参数就很容易理解,pVal传递进去的是变量的地址,cas通过这个来读取变量真实的值,oldVal传递的是变量在函数调用时的值,用来跟真实值进行比较,而newVal传递进去的是期望变量赋予的新的值。根据上面的cas的代码含义我们知道,当变量真实值不等于调用时的值的时候,是不会赋予变量新的值的。所以我们使用了一个WHILE来等待这个赋值成立。同时我们给与myValue一个volitale修饰,用意是让while中调用cas函数时,读取myValue的当前值,而不是寄存器中保存的值,以免变量值的“过期”,从而让这个cas可以在没有其他线程来修改myValue的时候执行成功,从而实现lock free的修改myValue。

在windows下,有专门的几个api来做cas这件事情,interlock开头的那些。当然,如果熟悉汇编,也可以自己去实现。

你可能感兴趣的:(java)