java多線程詳解(8)-volatile,Atomic比較


在變成過程中我們需要保證變量的線程安全,在java中除了使用鎖機制或者Threadlocal等保證線程安全,還提供了

java.util.concurrent.atomic.Atomic*(如AtomicInteger,AtomicLong等)原子類和volatile關鍵字是java中

兩種常見的處理多線程下數據共享讀寫的機制。

二者看似相同,但是在實際應用中有着不小的差別。

1.volatile關鍵字

volatile關鍵字是通過本地代碼實現的寫鎖,只保證知有一個線程在寫某個數據。JVM為了提高數據存取的速度,

允許每個線程在自己獨立的數據塊,對進程中共享的數據進行私有拷貝。volatile就是保證每次讀數據時,

讀的都是存在共享數據塊里的數據,而不是私有拷貝。然而,這種機制在有些情況下並不安全。

當兩個線程T1,T2同時對volatitle int i;作i++;時,可能出現問題。i++相當於為i=i+1。

T1 load i

T2 load i

T1 store i+1

T2 store i+1

這里應該執行兩次i=i+1,得到i=i+2的,但是結果確實i=i+1。

因此,這邊就有了Atomic原子類存在的價值了。Atomic類被設計來解決這個問題。

2.Atomic* 原子操作

關於atomic*原子操作,這里以AtomicInteger類為例

使用場景:

AtomicInteger,一個提供原子操作的Integer的類。在Java語言中,++i和i++操作並不是線程安全的,在使用的時候,

不可避免的會用到synchronized關鍵字。而AtomicInteger則通過一種線程安全的加減操作接口。

/**
 * Atomic原子性測試。
 * 
 * @author cary
 * @version 1.0.0
 */
public class AtomicTest {
    public static void main(String[] args) { AtomicInteger ai = new AtomicInteger(0); int i1 = ai.get(); print(i1); int i2 = ai.getAndSet(5); print(i2); int i3 = ai.get(); print(i3); int i4 = ai.getAndIncrement(); print(i4); print(ai.get()); } static void print(int i) { System.out.println("i : " + i); } }

結論: atomic比volatile靠譜


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM