current保重的atomic解析

来源:互联网 发布:js初始化 编辑:程序博客网 时间:2024/06/08 14:10

对于current中的automic应用,可以比较如下一段代码,他是线程安全的。通常的++操作会涉及到先get 再add的操作,是两个步骤的操作,所以在多线程操作的时候,会导致计数结果不准确。通常总数会小于我们期望的数值。

而使用atomic类,在底层采用了cas的原子指令:(引用)

CAS通过调用JNI的代码实现的。JNI:Java Native Interface为JAVA本地调用,允许java调用其他语言

而compareAndSwapInt就是借助C来调用CPU底层指令实现的。

下面从分析比较常用的CPU(intel x86)来解释CAS的实现原理。

 下面是sun.misc.Unsafe类的compareAndSwapInt()方法的源代码:

public final native boolean compareAndSwapInt(Object o, long offset,                                              int expected,                                              int x);
在底层操作的时候,会比较except和current是否一致,如一致,再+x或者-x。这个就是cas的原理。

因此对于上层调用,避免了线程不安全的因素。

如下代码:

package ReentrantLock;


import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;


public class ReentrantLockClass {
protected SeqAdd seq = new SeqAdd(0);
protected CountDownLatch latch = new CountDownLatch(10000);
protected SeqAutomic seqA = new SeqAutomic();

public void test(){
for(int i = 0;i<10000;i++){
new Thread(){
public void run(){
seq.increase();
seqA.increase();
latch.countDown();
}
}.start();
}
try {
latch.await();
System.out.println(seq.get());
System.out.println(seqA.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public  static void main(String[] args){
new ReentrantLockClass().test();
}

class SeqAdd{
SeqAdd(int count){
this.count = count;
}
private int count;
public int get(){
return count;
}
private void increase(){
count++;
}
private void decrease(){
count--;
}
}
class SeqAutomic{
private AtomicInteger count = new AtomicInteger(0);
public void increase(){
count.getAndIncrement();
}
public void decrease(){
count.getAndDecrement();
}
public int get(){
return count.get();
}
}
}



0 0
原创粉丝点击