标签(空格分隔): 操做系统html
/** * Atomically increments by one the current value. * * @return the previous value */ public final int getAndIncrement() { return unsafe.getAndAddInt(this, valueOffset, 1); } 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; }
Volatile不保证原子性的解决方案, 在其中咱们能够看到咱们经过
atomicInteger.getAndIncrement()
, 获取值而且将其+1, 重点在于this.compareAndSwapInt(var1, var2, var5, var5 + var4)
经过乐观锁的方法, 至关于实现了原子性的操做.java
import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicStampedReference; /** * CAS会致使ABA问题: * CAS算法实现一个重要前提须要取出内存中某时刻的数据而且在当下时刻进行比较并替换(Compare And Set), 那么在这个时间差的时候可能会致使数据的变化. * 好比: 一个线程one从内存位置中V中取出A, 这个时候另外一个线程two也从内存中取出A. 此时线程one和two都持有位置V中A的备份, 在这个时候two将A->B->A 并写入主存当中. * 线程one去进行CAS操做的时候, 发现内存中仍然是A, 而后线程one操做成功. * * 这个问题主要看线程two对中间操做对 线程one有影响没, 若是有影响的话. 须要解决一下CAS问题. */ public class Test { private static AtomicReference<Integer> atomicReference = new AtomicReference<>(100); private static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(100, 1); public static void main(String[] args) { /* ABA问题产生实例 Start */ new Thread(()->{ atomicReference.compareAndSet(100,101); atomicReference.compareAndSet(101,100); },"t1").start(); new Thread(()->{ try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(atomicReference.compareAndSet(100, 2019)+"\t"+atomicReference.get()); }).start(); /* ABA问题产生实例 End */ /* ABA问题解决实例 Start */ new Thread(() -> { int stamp = atomicStampedReference.getStamp(); System.out.println(Thread.currentThread().getName() + "\t 第一次版本号 : " + atomicStampedReference.getStamp()); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } atomicStampedReference.compareAndSet(100, 101, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1); System.out.println(Thread.currentThread().getName() + "\t 第二次版本号 : " + atomicStampedReference.getStamp()); atomicStampedReference.compareAndSet(101, 100, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1); System.out.println(Thread.currentThread().getName() + "\t 第三次版本号 : " + atomicStampedReference.getStamp()); }, "t3").start(); new Thread(() -> { int stamp = atomicStampedReference.getStamp(); System.out.println(Thread.currentThread().getName() + "\t 第一次版本号 : " + atomicStampedReference.getStamp()); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("是否修改为功: " + atomicStampedReference.compareAndSet(100, 2019, 1, atomicStampedReference.getStamp() + 1) + "\t 当前的stamp值: " + atomicStampedReference.getStamp()); System.out.println("当前最新值: " + atomicStampedReference.getReference()); }, "t4").start(); /* ABA问题 解决实例 End */ } }