原子类通过(CAS和volatile)实现单共享变量的线程安全

对于CAS是一种有别于synchronized的一种乐观锁实现.是一种非阻塞锁算法.CAS通过与原始预期值进行比较来确定是否修改主内存中数据的一种方案.基于一个线程的失败或者挂起不应该影响其他线程的失败或挂起这样的前提,而提出硬件层次的实现数据处理的互斥。可以自动更新共享数据,而且能够检测到其他线程的干扰,而 compareAndSet() 就用这些代替了锁定。对于实现CAS的原子类(AtomicInteger等)不仅仅对于单个贡献变量保证了原子性,同时借助volatile变量让共享变量保持可见性.,那么对于单个共享变量而言是可以实现线程安全的通信的,是不需要阻塞的同步方式比如synchronized实现同步。 下面我们通过一个例子来学习银行多线程并发取钱的实例.


1.单共享变量操作类

public class AtmicCounter {

   private  AtomicLong    balance;
   
   public  AtmicCounter(long  money)
   {
    balance=new  AtomicLong(money);
    System.out.println("当前金额--->"+balance);
   }
   
   //存钱
   public  void  deposit(long money)
   {
      balance.addAndGet(money);
   }
   
   //取钱(取money这么多钱)
   public  void  withDraw(long  money)
   {
     //取得当前值
    long  oldValue=this.balance.get();
    if(oldValue>0)
    {
     try {  
      
      Thread.sleep(10);
      if(this.balance.compareAndSet(oldValue, oldValue-money))
      {
            System.out.println(Thread.currentThread().getName()+" withDraw "+oldValue +" successful!!");
      }
  } catch (InterruptedException e) {
   
   e.printStackTrace();
  }
     
    }
   }
}

2.测试类

public class AtomicCounterTest  extends  Thread{
   private  AtmicCounter   counter;
  public  AtomicCounterTest(AtmicCounter   counter)
  {
   this.counter=counter;
  }
  
  public  void  run()
  { 
   while(true){
        this.counter.withDraw(1);
   }
  }

/**
  * 银行取钱测试
  */
public static void main(String[] args) {
  
  AtmicCounter   counter=new AtmicCounter(100);
  AtomicCounterTest   test1=new AtomicCounterTest(counter);
  AtomicCounterTest   test2=new AtomicCounterTest(counter);
  AtomicCounterTest   test3=new AtomicCounterTest(counter);
  AtomicCounterTest   test4=new AtomicCounterTest(counter);
  test1.start();
  test2.start();
  test3.start();
  test4.start();

}
}

小结:对于单变量情况可以通过原子类保证线程安全,但是多个共享变量不能保证.

原子类通过(CAS和volatile)实现单共享变量的线程安全,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。