Java代码:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
public class SmallerCASTest {
public static void main(String[] args){
final long MAX = 500l * 1000l * 1000l;
final AtomicLong counter = new AtomicLong(0);
long start = System.nanoTime();
while (true) {
if (counter.incrementAndGet() >= MAX) {
break;
}
}
long casTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
System.out.println("Time Taken=" + casTime + "ms");
}
}
C代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NITER 500000000
int main (){
long val = 0;
clock_t starttime = clock ();
while (val < NITER){
while (1){
long current = val;
long next = current+1;
if ( __sync_bool_compare_and_swap (&val, current, next))
break;
}
}
clock_t castime = (clock()-starttime)/ (CLOCKS_PER_SEC / 1000);
printf ("Time taken : %d ",castime);
}
运行
#!/bin/bash
gcc -O3 test.c -o test.o
echo -e "\nC"
./test.o
javac SmallerCASTest.java
echo -e "\nJava"
java SmallerCASTest
其他详情:
System : Linux XXXXXXXXX #1 SMP Thu Mar 22 08:00:08 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
gcc --version:
gcc (GCC) 4.4.6 20110731 (Red Hat 4.4.6-3)
java -version:
java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b04)
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01, mixed mode)
最佳答案
您确定我正在将苹果与橙子进行比较。 java
版本是真正的CAS,但在C
版本使用java
和synchronized
形式的调用时会失败,请重试。
有关更多详细信息,请参见this question。
有关该问题的说明,请参见this answer,其中说A full memory barrier is created when this function is invoked
,即用Java来讲,这是synchronized
调用。
尝试以与AtomicLong
使用它的java等价方式相同的方式来使用_compare_and_swap,即旋转该函数,直到该值更改为所需的值为止。
已添加:
我找不到与Java AtomicLong
等效的C++,但这并不意味着没有。本质上,任何线程都可以随时更改AtomicLong
,只有其中一个成功。但是,更改将是一致的,即更改将是一个或另一个线程进行更改的结果,而不是两者的组合。如果线程A尝试将值更改为0xffff0000(或等效的64位数字),而线程B尝试将值更改为0x0000ffff(同上),则结果将为或两个值的,更具体地说,它将为而不是为0x00000000或0xffffffff(当然,除非涉及到第三个线程)。
本质上,除此以外,AtomicLong
的所有都没有没有同步。