Java并发编程——CAS(Compare And Swap)比较与交换

前言

在Java并发编程中,处理共享数据的相关问题是保证并发安全的前提,对于一个共享数据,我们常常有两种处理方式,一种是方法是将数据和读写数据的操作锁起来,另一种就是不锁。

对于前者,Java中用synchronized关键字等进行加锁处理,这里不再多说。本文的重点,就是处理无锁状态下共享数据的并发问题中的一种解决算法——CAS(Compare And Swap)比较与交换算法。

乐观锁、悲观锁

首先先了解一下乐观锁和悲观锁,这两种锁分别假设下列两种情况:

乐观锁:假定访问共享数据的线程操作不会修改共享数据,因此采用不加锁的方式。

悲观锁:假定访问贡献数据的线程操作一定会修改贡献数据,因此采用加锁的方式来保证数据的同步性。

根据定义,很显然的能发现两种数据的应用环境,悲观锁适用于写操作比较多的环境当中,而乐观锁则适用于读操作比较多的环境当中。

其中,乐观锁的一个实现算法就是使用CAS算法。

CAS算法

比较与交换,该算法常常涉及三个变量,为此我们得先讲一下Java内存模型中的一些概念。

在Java内存模型中,每个线程有一个属于自己的缓存区,而多个线程共享一个主内存,在并发环境中,多个线程从主内存中读取数据缓存到自己的缓存区,当执行写操作时再写入缓存区。

因此,CAS涉及的变量为:一个旧值(线程缓存区的值),一个主存值(主内存中的值),一个新值。

当一个线程执行该操作时,需要先将旧值和主存值比较,只有当二者相等时,才会执行新值的更新操作,并同时将新值写入主存,即也会更新主存值。

于是,当两个线程同时访问一个共享数据时,就会执行该操作,同时CAS操作时原子操作,由此而保证了贡献数据访问的安全。

基于乐观锁的机制,当一个线程执行CAS操作时,另一个线程会自旋等待,直到执行到CAS操作。

CAS操作的问题

  • ABA问题
  • 自旋带来的性能问题

你可能感兴趣的:(java,多线程,并发编程)