一、什么是原子性
簡單的可以理解為:操作是不可再分割的,比如;
int i=0;
但是i++的操作是可以再分的,比如:
i++ //分解后 i=i+i
上面的代碼在多線程環境下取值是有問題的,比如:
package com.example.demo.juc; /** * @author DUCHONG * @since 2019-01-07 19:11 **/ public class AtomicTest { public static void main(String[] args) { AtomicThread atomicTest=new AtomicThread(); for (int i=1;i<=20;i++){ new Thread(atomicTest).start(); } } } class AtomicThread implements Runnable { private int num=1; @Override public void run() { try { Thread.sleep(300); System.out.println(getNum()); } catch (InterruptedException e) { e.printStackTrace(); } } public int getNum(){ return num++; } }
結果:
這種問題當然可以通過加synchronized 關鍵字來解決,那有沒有另外一種方案呢,答案肯定是有的,且在jdk1.5的時候就有了,那就是Atomic包下的原子類
優化后:
package com.example.demo.juc; import java.util.concurrent.atomic.AtomicInteger; /** * @author DUCHONG * @since 2019-01-07 19:11 **/ public class AtomicTest { public static void main(String[] args) { AtomicThread atomicTest=new AtomicThread(); for (int i=1;i<=20;i++){ new Thread(atomicTest).start(); } } } class AtomicThread implements Runnable { private AtomicInteger at=new AtomicInteger(1); @Override public void run() { try { Thread.sleep(300); System.out.println(getNum()); } catch (InterruptedException e) { e.printStackTrace(); } } public int getNum(){ return at.getAndIncrement(); } }
看源碼:
構造函數中的值,是volatile類型的
自增或者自減時,使用了CAS算法,CAS算法有三個操作數:
內存值:A
預估值:B
新值:V
當且僅當 A=B 是 A=V
否則不做任何操作。