在学习CAS无锁时候,总是难免拿来与Synchronized进行比较。
首先先来说一下无锁算法的基本思想:
要实现无锁(lock-free)的非阻塞算法有多种实现方法,其中 CAS(比较与交换,Compare and swap) 是一种有名的无锁算法。CAS, CPU指令,在大多数处理器架构,包括IA32、Space中采用的都是CAS指令,CAS的语义是“我认为V的值应该为A,如果是,那么将V的值更新为B,否则不修改并告诉V的值实际为多少”,CAS是项 乐观锁 技术,当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
这里讲一个JVM当中的CAS应用:
JVM对CAS的支持:AtomicInt, AtomicLong.incrementAndGet()
具体事例(下面会用到):
/**
* Atomically increments by one the current value.
*
* @return the updated value
*/
public final long incrementAndGet() {
for (;;) {
long current = get();
long next = current + 1;
if (compareAndSet(current, next))
return next;
}
}
为了比较其与Synchronized关键字的性能比较,我在这里做了一个测试,测试结果:
通过以上对比可以明显的发现,使用Atomic的性能要优于Synchronized
具体的代码实现:首先,设计一个类,用于记录运行的时间:
package com.test;
public class StopWatch {
private long starttime =0;
private long stoptime =0;
private boolean running =false;
public void start() {
// TODO Auto-generated method stub
this.starttime = System.currentTimeMillis();
this.running = true;
}
public void stop() {
// TODO Auto-generated method stub
this.stoptime = System.currentTimeMillis();
this.running = false;
}
public long getRunningTime() {
// TODO Auto-generated method stub
long runningTime;
if(running){
runningTime = System.currentTimeMillis()-starttime;
}else{
runningTime = stoptime-starttime;
}
return runningTime;
}
public long getRunningTimeSec() {
// TODO Auto-generated method stub
long runningTimeSec;
if(running){
runningTimeSec = (System.currentTimeMillis()-starttime)/1000;
}else{
runningTimeSec = (stoptime-starttime)/1000;
}
return runningTimeSec;
}
}
接着是测试类的内容:
package com.test;
import java.util.concurrent.atomic.AtomicLong;
public class SyncAtomicTest {
public static void main(String[] args) {
System.out.println("------START !------");
calc(); //不加任何绑定
calcSyn(); //单线程Synchronized关键字
calcAtomic(); //单线程Atomic关键字
testThreadsSync(); //多线程Synchronized关键字
testThreadAtomic(); //多线程Synchronized关键字
testThreadsSync();
testThreadAtomic();
System.out.println("------FINISHED !------");
}
private static void calc() {
// TODO Auto-generated method stub
StopWatch sw = new StopWatch();
sw.start();
long var =0;
while(var<10000000L){
var++;
}
long runningTime = sw.getRunningTime();
System.out.println("calc runningTime: "+runningTime);
}
private static void calcSyn() {
// TODO Auto-generated method stub
StopWatch sw = new StopWatch();
sw.start();
long var =0;
while(var<10000000L){
synchronized (SyncAtomicTest.class) {
var++;
}
}
long runningTime = sw.getRunningTime();
System.out.println("calcSyn runningTime: "+runningTime);
}
private static void calcAtomic() {
// TODO Auto-generated method stub
StopWatch sw = new StopWatch();
sw.start();
AtomicLong var =new AtomicLong(0);
while(var.incrementAndGet()<10000000L){
}
long runningTime = sw.getRunningTime();
System.out.println("calcAtomic runningTime: "+runningTime);
}
private static void testThreadsSync() {
// TODO Auto-generated method stub
StopWatch sw = new StopWatch();
sw.start();
Thread t1 = new Thread(new LoopSync());
t1.start();
Thread t2 = new Thread(new LoopSync());
t2.start();
while(t1.isAlive()||t2.isAlive()){
}
sw.stop();
long runningTime = sw.getRunningTime();
System.out.println("thread sync runningTime :"+ runningTime);
}
private static class LoopSync implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
long var =0;
while(var <10000000L){
synchronized (SyncAtomicTest.class) {
var++;
}
}
}
}
private static void testThreadAtomic() {
// TODO Auto-generated method stub
StopWatch sw = new StopWatch();
sw.start();
Thread t1 = new Thread(new LoopAtomic());
t1.start();
Thread t2 = new Thread(new LoopAtomic());
t2.start();
while(t1.isAlive()||t2.isAlive()){}
sw.stop();
long runningTime = sw.getRunningTime();
System.out.println("thread atomic runningTime :"+ runningTime);
}
private static class LoopAtomic implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
AtomicLong var =new AtomicLong(0);
while(var.incrementAndGet() <10000000L){
}
}
}
}
4326



被折叠的 条评论
为什么被折叠?



