核心类
是Unsafe
核心方法
compareAndSet(旧值,新值);
如何应用?
1.Unsafe.compareAndSet(旧值,新值);
2.自己实现工具类 //必须包含一个数据,这个数据就是旧值
最核心的东西,就是上面两个东西。
代码
自定义工具类{
private Unsafe unsafe; //提供比较然后设置方法的功能
private volatile int oldValue; //保存旧值
}
具体步骤
1.读取旧值 //自定义工具类.oldValue;
2.比较然后设置 //Unsafe.compareAndSet(旧值,新值);
3.true,就设置新的值;false,就不设置 //Unsafe.compareAndSet(旧值,新值); 的返回结果
应用场景
1.原子计数器AtomicInteger
2.显式锁AbstractQueuedSynchronizer
他们的实现,都是跟我们的自定义工具类是一样的原理,就是核心两步
1.private Unsafe unsafe; //提供比较然后设置方法的功能
2.private volatile int oldValue; //保存旧值
比较,到底是在比较什么?到底是如何比较?
比较的到底又是哪些值?
本质是
1.自定义实现类.get旧值(); //这里的旧值,就是自定义类的数据
2.Unsafe.compareAndSet(旧值,新值); //这里的旧值,就是第一步读的数据
旧值分别是哪个,弄清楚了。现在的问题是,Unsafe.compareAndSet(旧值,新值);里的旧值,到底是在和谁比较?还是和自定义实现类的数据进行比较。
因为第一步,和第二步,是两个操作,所以这两个操作不是原子的,因此,Unsafe.compareAndSet(旧值,新值); 的返回值才会有true或false两种情况。
真正原子的地方,是Unsafe.compareAndSet(旧值,新值);这个方法本身。即包含了1.比较校验数据2.设置新的数据,这两步操作。
最佳实践
一般都是直接使用jdk提供的工具类,工具类的本质是封装了1.Unsafe //用于比较设置 2.数据 //用于同步。
除非jdk不能满足需求,才会自己去实现工具类。
本质
比较设置,本质是为了解决线程安全问题,
工具类
作用就是同步工具类。本质也是为了解决线程安全问题。
不管是谁实现的,你自己实现的,还是jdk实现的,作用和要解决的问题是一样的。