當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Java Atomic Variables用法及代碼示例


多線程,共享實體主要會在以下情況下導致問題:並發性被合並。共享實體,例如,可變的對象或變量可能會被更改,這可能會導致程序的不一致或數據庫。因此,在並發訪問時處理共享實體變得至關重要。一個原子變量可以是這種情況下的替代方案之一。

Java提供原子類AtomicInteger,AtomicLong,AtomicBooleanAtomicReference。這些類的對象代表原子變量分別為 int、long、boolean 和對象引用。這些類包含以下方法。

  1. 設置(整數值):設置為給定值
  2. get():獲取當前值
  3. 惰性設置(int值):最終設置為給定值
  4. CompareAndSet(int期望,int更新):如果當前值 == 預期值,則自動將該值設置為給定的更新值
  5. addAndGet(int delta):以原子方式將給定值添加到當前值
  6. decrementAndGet():以原子方式將當前值減一

例子:

// Atomic Variable
AtomicInteger var;

需要原子變量
考慮下麵的例子:

Java


class Counter extends Thread {
    // Counter Variable
    int count = 0;
    // method which would be called upon
    // the start of execution of a thread
    public void run()
    {
        int max = 1_000_00_000;
        // incrementing counter
        // total of max times
        for (int i = 0; i < max; i++) {
            count++;
        }
    }
}
public class UnSafeCounter {
    public static void main(String[] args)
        throws InterruptedException
    {
        // Instance of Counter Class
        Counter c = new Counter();
        // Defining Two different threads
        Thread first = new Thread(c, "First");
        Thread second = new Thread(c, "Second");
        // Threads start executing
        first.start();
        second.start();
        // main thread will wait for
        // both threads to get completed
        first.join();
        second.join();
        // Printing final value of count variable
        System.out.println(c.count);
    }
}
輸出:
137754082

在單線程環境中,上述類隻會給出預期的結果。但當涉及到多線程環境時,可能會導致結果不一致。發生這種情況是因為更新 “var” 是通過三個步驟完成的:讀取、更新和寫入。如果兩個或更多線程嘗試同時更新該值,則它可能無法正確更新。

這個問題可以使用 Lock and Synchronization 解決,但效率不高。

1.使用鎖類比或同步:同步或鎖定可以解決我們的問題,但它會損害時間效率或性能。首先,它要求資源和線程調度程序來控製鎖。其次,當多個線程嘗試獲取鎖時,隻有一個線程獲勝,其餘線程被掛起或阻塞。掛起或阻塞線程會對性能產生巨大影響。

Java


import java.io.*;
import java.util.concurrent.locks.*;
class Counter extends Thread {
    // Counter Variable
    int count = 0;
    // method which would be called upon
    // the start of execution of a thread
    public synchronized void run()
    {
        int max = 1_000_00_000;
        // incrementing counter total of max times
        for (int i = 0; i < max; i++) {
            count++;
        }
    }
}
public class SynchronizedCounter {
    public static void main(String[] args)
        throws InterruptedException
    {
        // Instance of Counter Class
        Counter c = new Counter();
        // Defining Two different threads
        Thread first = new Thread(c, "First");
        Thread second = new Thread(c, "Second");
        // Threads start executing
        first.start();
        second.start();
        // main thread will wait for both
        // threads to complete execution
        first.join();
        second.join();
        // Printing final value of count variable
        System.out.println(c.count);
    }
}
輸出:
200000000

2.使用原子變量:

Java


import java.util.concurrent.atomic.AtomicInteger;
class Counter extends Thread {
    // Atomic counter Variable
    AtomicInteger count;
    // Constructor of class
    Counter()
    {
        count = new AtomicInteger();
    }
    // method which would be called upon
    // the start of execution of a thread
    public void run()
    {
        int max = 1_000_00_000;
        // incrementing counter total of max times
        for (int i = 0; i < max; i++) {
            count.addAndGet(1);
        }
    }
}
public class AtomicCounter {
    public static void main(String[] args)
        throws InterruptedException
    {
        // Instance of Counter Class
        Counter c = new Counter();
        // Defining Two different threads
        Thread first = new Thread(c, "First");
        Thread second = new Thread(c, "Second");
        // Threads start executing
        first.start();
        second.start();
        // main thread will wait for both
        // threads to complete execution
        first.join();
        second.join();
        // Printing final value of count variable
        System.out.println(c.count);
    }
}
輸出:
200000000


相關用法


注:本文由純淨天空篩選整理自NiravTalaviya大神的英文原創作品 Atomic Variables in Java with Examples。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。