標籤:string oid 就會 帶來 存在 定義 編程 面試官 atom
參考資料:https://fangjian0423.github.io/2016/03/16/java-AtomicInteger-analysis/
http://www.cnblogs.com/549294286/p/3766717.html
最近面試遇到一道編程題,要求兩個線程交替列印[0,100]的數字,其中一個只列印奇數,另一個只列印偶數,並且給出特別明顯的提示AtomicInteger,當時我在想簡直是送分題啊,但事後回想由於手寫又沒有記得所有API,很多地方不完美,所以面試官最後讓我解釋一下,回來再用IDE寫一遍就順暢多了,解題思路:
- 定義thread0輸出奇數,thread1輸出偶數
- thread0執行時,若當前值為偶數則進入waiting狀態並煥醒thread1
- thread1執行時,若當前值為奇數則進入waiting狀態並煥醒thread0
- 迴圈執行上兩步直到當前值達到100
import java.util.concurrent.atomic.AtomicInteger;/** * @Description: 測試AtomicInteger*/public class AtomicIntegerTest { private static AtomicInteger num = new AtomicInteger(0); public static void main(String[] args) { MyThead thread0 = new MyThead(1); MyThead thread1 = new MyThead(0); thread0.start(); thread1.start(); } public static class MyThead extends Thread { private int v; public MyThead(int v) { this.v = v; } @Override public void run() { synchronized (num) { while (num.get() < 100) { if (v == 1) { if (num.get() % 2 == 0) { try { num.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else { System.out.println(num.incrementAndGet()); num.notifyAll(); } } else if (v == 0) { if (num.get() % 2 == 1) { try { num.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else { System.out.println(num.incrementAndGet()); num.notifyAll(); } } } } } }}
從AtomicInteger類源碼可以看到,它定義了一個volatile的變數value用於儲存值,而所有的操作都藉助Unsafe類的操作來完成,Unsafe類的許多操作為CAS,可以理解為內建樂觀鎖,樂觀鎖就會存在ABA問題,但由於AtomicInteger儲存的是int元素,這個問題幾乎可以忽略,故可認為它是安全執行緒的。然而對於AtomicReference來說,ABA問題就可能帶來致命問題,因此有了AtomicStampedReference類來解決這個問題。
Java多線程系列一——Atomic類