CAS操作号称无锁优化,也叫作自旋;对于一些常见的操作需要加锁,然后jdk就提供了一些以Atomic开头的类,这些类内部自动带了锁,当然这里的锁并非是用synchronized来实现的,而是通过CAS操作来实现的;
package com.designmodal.design.juc01; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; /** * @author D-L * @Classname T03_AtomicInteger * @Version 1.0 * @Description 使用 AtomicInteger 类解决常见的 多线程count++ * 其内部使用了CAS操作来保证原子性 但是不能保证多个方法连续调用都是原子性 * @Date 2020/7/21 0:35 */ public class T03_AtomicInteger { //使用AtomicInteger类 AtomicInteger count = new AtomicInteger(0); public void m(){ for (int i = 0; i < 10000; i++) { //等同于 在 count++ 上加锁 count.incrementAndGet(); } } public static void main(String[] args) { T03_AtomicInteger t = new T03_AtomicInteger(); List<Thread> threads = new ArrayList<>(); for (int i = 0; i < 10; i++) { threads.add(new Thread(t::m , "Thread" + i)); } threads.forEach((o) -> o.start()); threads.forEach(o ->{ try { o.join(); } catch (InterruptedException e) { e.printStackTrace(); } }); System.out.println(t.count); } }
1、首先小程序中定义了一个 AtomicInteger 类型的变量count;
AtomicInteger count = new AtomicInteger(0);
public void add(){
count.incrementAndGet();
}
/** * Atomically increments by one the current value. * * @return the updated value */ public final int incrementAndGet() { return unsafe.getAndAddInt(this, valueOffset, 1) + 1; }
3、调用unsafe类中的 getAndAddInt(Object var1, long var2, int var4)方法;
public native int getIntVolatile(Object var1, long var2); public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5); public final int getAndAddInt(Object var1, long var2, int var4) { int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); return var5; }
这里通过以上三步的操作,最终会进入Unsafe类这里调用的 compareAndSwapInt 意思就是比较然后交换,通过一个while循环,在这里转呀转,直到修改成功;
CAS(compareAndSwap)(比较并交换):原来想改变的值为0 ,现在想修改成1 ,这里想做到线程安全就必须要加synchronized,现在想用另外一种方式来替换加锁的方法,就是所谓的CAS操作;你可以把它想象成拥有三个参数的方法cas(V , Expected , NewValue);
原文:https://www.cnblogs.com/dongl961230/p/13352744.html