cas

在大多数处理器架构中采用的方法是实现一个比较并交换(CAS)指令。CAS包含了3个操作数——需要读写的内存位置V、进行比较的值A和拟写入的新值B。当且仅当V的值等于A时,CAS才会通过原子方式用新值B来更新V的值,否则不会执行任何操作。无论位置V的值是否等于A,都将返回V原有的值。(这种变化形式被称为比较并设置,无论操作是否成功都会返回。)CAS的含义是:“我认为V的值应该为A,如果是,那么将V的值更新为B,否则不修改并告诉V的值实际为多少”。CAS是一项乐观的技术,它希望能成功地执行更新操作,并且如果有另一个线程在最近一次检查后更新了该变量,那么CAS能检测到这个错误。代码如下:

public class SimulatedCAS {

	private int value;
	
	public synchronized int get() {return value;}
	
	public synchronized int compareAndSwap(int expectedValue, int newValue){
		
		int oldValue = value;
		if(oldValue == expectedValue)
			value = newValue;
		return oldValue;
	}
	
	public synchronized boolean compareAndSet(int expectedValue, int newValue){
		return expectedValue == compareAndSwap(expectedValue, newValue);
	}
}

当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其他线程都将失败。然而,失败的线程并不会被挂起(这与获得锁的情况不同:当获取锁失败时,线程将被挂起),而是被告知在这次竞争中失败,并可以再次尝试。由于一个线程在竞争CAS时失败不会阻塞,因此它可以决定是否重新尝试,或者执行一些恢复操作,也或者不执行任何操作。

非阻塞计数器

CasCounter使用CAS实现了一个线程安全的计数器。递增操作采用了标准形式——读取旧的值,根据它计算新值,并使用CAS来设置这个新值。如果CAS失败,那么该操作将立即重试。

public class CasCounter {
    private SimulatedCAS value;
    
    public int getValue(){
        return value.get();
    }
    
    public int increment() {
        int v;
        do{
            v = value.get();
        }while(v != value.compareAndSwap(v,v+1));
        return v+1; 
    }
}

当竞争程序不高时,基于CAS的计数器在性能上远远超过了基于锁的计数器,而在没有竞争时甚至更高。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值