import java.util.concurrent.atomic.AtomicInteger;import java.util.concurrent.atomic.AtomicLong;import java.util.concurrent.atomic.LongAdder;/** * @version 1.0.0 * @Author Meir * @copyright(C) */public class SynchronizedTest { /** * 性能 LongAdder > AtomicInteger > 直接加synchronized */ public static void main(String[] args) throws InterruptedException { At a = new At(); long l1 = System.currentTimeMillis(); Thread thread = new Thread(() -> { for (int i = 0; i < 1000000; i++) { a.atomicIntegerIncrease(); } }); thread.start(); for (int i = 0; i < 1000000; i++) { a.atomicIntegerIncrease(); } thread.join(); System.out.println(System.currentTimeMillis() - l1); System.out.println(a.getNum( )); } static class At { int num = 0; //1.原子操作integer //内部实现-CAS 比较并交换 AtomicInteger atomicInteger = new AtomicInteger(); //2. LongAdder longAdder = new LongAdder(); public int getNum() {// return num; return atomicInteger.get();// return longAdder.longValue(); }// 不加锁不安全 public void increase() { num ++; } /** * synchronized锁的是同步代码块 this方法 */ public synchronized void synchronizedIncrease() { num ++; //效果一样 锁的是同步代码块 this方法// synchronized (this) {// num ++;// } } /** * AtomicInteger */ public synchronized void atomicIntegerIncrease() { atomicInteger.incrementAndGet(); //实现步骤 自旋比较 //CAS机制中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B。 //更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。// while (true) {// int oldNum = atomicInteger.get();// int newNum = oldNum + 1;// //compareAndSet底层是一个原子操作 c++对他底层汇编的cmoxchgq(Compare exchange 比较交换)方法有加锁 (缓存行锁/总线锁)// if (atomicInteger.compareAndSet(oldNum, newNum)) {// break;// }// } //ABA问题 :有线程在改值时 拿到旧值A 在+1生成B时另一线程如果速度更快 把旧值A改成C再改成A //解决:加版本号version 每次操作版本+1 C改A版本就是3 1线程A改B就会发现版本不一致不修改 //例如类:AtomicStampedReference compareAndSet方法加了stamp标记 } /** * LongAdder */ public synchronized void LongAdderIncrease() { //底层实现CAS分段优化机制 自动迁移机制 //当多个线程进行修改时,使用多个cell单元格,每个cell value初始值为0,分散多个线程的请求压力 //如果需要求和 则将base和所有的cell加起来即可 //当线程增多,每个cell中分配的线程数也会增多,当其中一个线程操作失败的时候 //它会自动迁移到下一个cell中进行操作,这也就解决了CAS空旋转,自旋不停等待的问题。这就是 自动迁移机制。 longAdder.increment(); } }}