对数字进行多线程递增操作
static AtomicLong atomicLong = new AtomicLong(0);
static volatile int num = 0;
static void incr() {
num++;
}
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 1000; j++) {
new Thread(() -> {
atomicLong.getAndIncrement();
incr();
}).start();
}
}
while (Thread.activeCount() > 2) {
Thread.yield();
}
System.out.println("Atomic:"+atomicLong);
System.out.println("int:"+num);
}
结果-------
可以看到同样是进行递增操作,普通的int在进行 num++ 操作是非原子性的,atomic包下边的类进行递增可以保证原子性
AtomicLong 的CAS操作
static AtomicLong atomicLong = new AtomicLong(0);
public static void main(String[] args) throws Exception {
new Thread(()-> {
boolean compareAndSet = atomicLong.compareAndSet(0, 1);
System.out.println(Thread.currentThread().getName()+" "+compareAndSet);
},"A").start();
new Thread(()-> {
boolean compareAndSet = atomicLong.compareAndSet(0, 1);
System.out.println(Thread.currentThread().getName()+" "+compareAndSet);
},"B").start();
TimeUnit.SECONDS.sleep(1);
System.out.println("Atomic:"+atomicLong);
}
结果
CAS的ABA问题
static AtomicLong atomicLong = new AtomicLong(0);
public static void main(String[] args) throws Exception {
new Thread(()-> {
boolean compareAndSet = atomicLong.compareAndSet(0, 1);
System.out.println(Thread.currentThread().getName()+" "+compareAndSet);
},"A").start();
new Thread(()-> {
boolean compareAndSet = atomicLong.compareAndSet(1, 0);
System.out.println(Thread.currentThread().getName()+" "+compareAndSet);
},"C").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()-> {
boolean compareAndSet = atomicLong.compareAndSet(0, 1);
System.out.println(Thread.currentThread().getName()+" "+compareAndSet);
},"B").start();
TimeUnit.SECONDS.sleep(1);
System.out.println("Atomic:"+atomicLong);
}
结果
为了防止ABA问题atomic包下的 AtomicStampedReference 利用版本进行控制
static AtomicStampedReference<Long> atomicStampedReference = new AtomicStampedReference<Long>(0L, 0);
public static void main(String[] args) throws Exception {
new Thread(()-> {
boolean compareAndSet = atomicStampedReference.compareAndSet(0L, 2L, 0, 1);
System.out.println(Thread.currentThread().getName()+" "+compareAndSet);
},"A").start();
new Thread(()-> {
boolean compareAndSet = atomicStampedReference.compareAndSet(2L, 0L, 0, 1);
System.out.println(Thread.currentThread().getName()+" "+compareAndSet);
},"C").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()-> {
boolean compareAndSet = atomicStampedReference.compareAndSet(0L, 1L, 0, 1);
System.out.println(Thread.currentThread().getName()+" "+compareAndSet);
},"B").start();
TimeUnit.SECONDS.sleep(1);
System.out.println("Atomic:"+atomicStampedReference.getReference());
}
结果-----
AtomicStampedReference构造方法初始化存在两个参数,第一个是泛型对应的对象,第二个是版本号