一、CAS简介
CAS:Compare and Swap, 翻译成比较并交换。
java.util.concurrent包中借助CAS实现了区别于synchronouse同步锁的一种乐观锁,使用这些类在多核CPU的机器上会有比较好的性能.
CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
今天我们主要是针对AtomicInteger的incrementAndGet做深入分析。
二、JAVA实现部分
/** * Atomically increments by one the current value. * * @return the updated value */ public final int incrementAndGet() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return next; } }
循环的内容是
1.取得当前值
2.计算+1后的值
3.如果当前值没有被覆盖的话设置那个+1后的值
4.如果设置没成功, 再从1开始
在这个方法中可以看到compareAndSet这个方法,我们进入看一下。
/** * Atomically sets the value to the given updated value * if the current value {@code ==} the expected value. * * @param expect the expected value * @param update the new value * @return true if successful. False return indicates that * the actual value was not equal to the expected value. */ public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); }
调用UnSafe这个类的compareAndSwapInt
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
JAVA程序也就跟踪到这里为止了,剩下的就是通过JNI调用C程序了,可是我奇怪的是为什么变量名都是var1,var2这样的命名呢?JAVA编程规范不是说不使用1,2等没有含义的字符命名吗?
三、JNI原生实现部分
在openJDK中找到找到unsafe.cpp这个文件,代码如下:
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) UnsafeWrapper("Unsafe_CompareAndSwapInt"); oop p = JNIHandles::resolve(obj); jint* addr = (jint *) index_oop_from_field_offset_long(p, offset); return (jint)(Atomic::cmpxchg(x, addr, e)) == e; UNSAFE_END
核心方法是compxchg,这个方法所属的类文件是在OS_CPU目录下面,由此可以看出这个类是和CPU操作有关,进入代码如下:
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { // alternative for InterlockedCompareExchange int mp = os::is_MP(); __asm { mov edx, dest mov ecx, exchange_value mov eax, compare_value LOCK_IF_MP(mp) cmpxchg dword ptr [edx], ecx } }
这个方法里面都是汇编指命,看到LOCK_IF_MP也有锁指令实现的原子操作,其实CAS也算是有锁操作,只不过是由CPU来触发,比synchronized性能好的多。
相关推荐
这些类的原子操作,如`getAndSet`、`compareAndExchange`等,都是基于`Unsafe`的CAS操作实现的。 下面是一个简单的示例,展示如何使用`Unsafe`进行CAS操作: ```java import com.walking.juc.util.UnsafeUtil; ...
- `boolean compareAndSet(int i, int expect, int update)`:如果数组中索引`i`处的值等于`expect`,则以原子方式将其设置为`update`。 3. **AtomicReference** - `V getAndSet(V newValue)`:以原子方式设置为...
if (ref.compareAndSet(obj, new MyObject(), stamp, stamp + 1)) { System.out.println("更新成功"); } else { System.out.println("更新失败,有其他线程修改了引用或版本号"); } ``` **四、优缺点** 优点:...
CAS操作 CAS是单词compare and set的缩写,意思是指在set之前先比较该值有没有变化,只有在没变的情况下才对其赋值。 我们常常做这样的操作 ... if(a.compareAndSet(expect,a+1)) { doSomeThing1();
例如,`compareAndSet()`方法就是用于执行CAS操作,它的使用通常包括以下步骤: 1. 读取当前值:线程首先读取变量的当前值。 2. 拟定新值:根据当前值计算出期望的新值。 3. CAS更新:使用`compareAndSet()`尝试将...
这些类中的方法如compareAndSet()就是实现CAS操作的关键。 CAS的优势在于它避免了锁的开销,减少了上下文切换,提高了并发性能。然而,CAS也有其局限性,比如ABA问题。如果一个值从A变为B,然后再变回A,CAS可能会...
有关java高并发知识总结:三种线程创建方式 深入理解Thread构造函数 Thread API #### CAS缺陷 ##### 循环时间长开销大,自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。 ##### 只能保证一个共享变量...
2. **并发锁机制**:`08-并发锁机制之深入理解synchronized(二)-fox`和`07-并发锁机制之深入理解synchronized(一)-fox`主要讲解了`synchronized`关键字。它是Java中的内置锁,用于控制对共享资源的访问,保证...
- **compareAndSet**: 对象的期望值与实际值相等时,才将对象的值设置为新值。 - **ABA问题**: 如果在两次检查之间,变量的值被其他线程修改回原来值,则CAS机制无法检测到这一变化,这被称为ABA问题。 - **解决ABA...
- **无锁数据结构**:如`AtomicIntegerArray`等原子类,使用CAS(Compare and Swap)操作实现线程安全。 6. **并发容器的使用注意事项**: - 避免不必要的同步:只在必要时才使用线程安全的容器,否则可能会带来...
- `compareAndSet(int expect, int update)`:如果当前值等于预期值,则将其设置为给定的更新值,并返回`true`;否则返回`false`。 - `decrementAndGet()`:以原子方式将当前值减1。 - `get()`:获取当前值。 - ...
Java提供了`AtomicInteger`、`AtomicLong`等原子类,它们的原子方法如`compareAndSet`、`incrementAndGet`等,能够在不引入锁的情况下保证操作的原子性。例如,`AtomicInteger`的`addAndGet`方法,能够实现线程安全...
如果在检查旧值和尝试更新之间,有其他线程改变了变量,`compareAndSet()`会失败,从而避免了数据的不一致性。 清单1展示了使用`synchronized`关键字实现的线程安全计数器,每次`increment()`方法都会获取锁,完成...
为了保证线程安全,AQS提供了一个基于CAS(Compare and Set)操作的`compareAndSetTail()`方法来设置队列的`tail`节点。这一机制确保了队列的操作是原子性的,从而避免了数据竞争和不一致的问题。 综上所述,AQS...
Java提供了诸如AtomicInteger、AtomicLong、AtomicReference等原子变量类,这些类提供了基于CAS的原子操作,例如incrementAndGet()、compareAndSet()等方法,可以在不使用锁的情况下实现线程安全的更新。 **3.2.4 ...
}compareAndSet调用了unsafe.compareAndSwapInt,这是一个native方法,原理就是调用硬件支持的CAS方法。 CAS是一种高效的同步机制,它可以减少因为阻塞而损失的性能,提高多线程并发环境下的性能。但是,CAS操作...
《深入理解CAS机制及其在Java中的应用》 CAS(Compare and Swap,比较并交换)是计算机硬件层面提供的一种原子操作,常被用于并发编程中,以实现无锁数据结构。在Java中,JUC(Java Util Concurrency)库通过`java....
if (compareAndSet(current, next)) return current; } } ``` 这个方法会持续尝试自增,直到成功为止。 2. 当资源竞争非常激烈时,synchronized可能更优。因为synchronized会将线程挂起,避免了自旋造成的CPU...
CAS(Compare-And-Swap)是一种无锁机制,用于实现线程安全的更新操作。CAS 操作包括三个参数:expected value、new value 和当前值。如果当前值等于 expected value,那么就将当前值更新为 new value。 6. 线程池 ...