volatile關鍵字:若是一個變量聲明爲volatile後,每一個線程操做共享變量後就會當即同步到主存中,此功能是底層硬件支持的。也就是說volatile關鍵字解決了共享變量的可見性問題,但沒有解決變量的原子性以及互斥性。 原子類中的變量所有聲明爲volatile,保證線程可見性,原子類使用cas算法保證原子性。java
public class VolatileDemo { public static void main(String[] args) { ThreadClass threadClass = new ThreadClass(); Thread thread = new Thread(threadClass); thread.start(); while (true){ if (threadClass.shareVar){//在這裏main線程訪問共享變量,該共享變量是main線程的變量副本 System.out.println("ShareVariableClass.shareVar:" + threadClass.shareVar); break; } } } } class ThreadClass implements Runnable{ public volatile boolean shareVar = false; @Override public void run() { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } this.shareVar = true; System.out.println("sharVar change to " + shareVar); } }
結果以下,結果中打印的順序會不一致。
算法
CAS:全稱compare and swap,比較並交換。當多個線程操做共享變量的時候,每一個線程的操做都寫入主存中,就會致使主存中的共享變量不可以保證原子性。若是要操做一個變量s進行+1操做,在+操做以前,獲取主存中s的值(經過volatile關鍵字保證可見性)做爲指望值expectValue,將s進行+1操做後,寫入主存以前經過將目前的主存值和expectValue值作比較,若是相同則將s+1的值寫入主存,若是不相等,則重複進行上述步驟。緩存
以AtomicInteger舉例ide
AtomicInteger atomicInteger = new AtomicInteger(10); int andIncrement = atomicInteger.getAndIncrement();
cas操做最終調用的方法是Unsafe類中的native方法調用,除了Integer類型的原子操做,還有Boolean等的類型操做,但調用是以下三個方法來保證原子性。boolean類型是經過轉換爲int類型來進行操做的。
this
全部原子類以下
atom