今天我們將研究 Java 中的 AtomicInteger
。 原子操作 是在單個任務單元中執行的,不會受到其他操作的干擾。 在多線程環境中,原子操作是必要的,以避免數據不一致性。
AtomicInteger
讓我們創建一個簡單的多線程程序,其中每個線程將共享的
count
變量增加 4 次。 因此,如果有兩個線程,則在它們完成後,count
的值應該為 8。 JavaAtomic.java
package com.journaldev.concurrency;
public class JavaAtomic {
public static void main(String[] args) throws InterruptedException {
ProcessingThread pt = new ProcessingThread();
Thread t1 = new Thread(pt, "t1");
t1.start();
Thread t2 = new Thread(pt, "t2");
t2.start();
t1.join();
t2.join();
System.out.println("Processing count=" + pt.getCount());
}
}
class ProcessingThread implements Runnable {
private int count;
@Override
public void run() {
for (int i = 1; i < 5; i++) {
processSomething(i);
count++;
}
}
public int getCount() {
return this.count;
}
private void processSomething(int i) {
// 處理某些工作
try {
Thread.sleep(i * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
如果您運行上面的程序,您將注意到 count
的值在 5、6、7、8 之間變化。 原因是因為 count++ 不是原子操作。 因此,當一個線程讀取它的值並將其增加一時,其他線程已經讀取了舊值,導致了錯誤的結果。 要解決這個問題,我們必須確保對 count 的增量操作是原子的,我們可以使用 同步 來做到這一點,但是 Java 5 java.util.concurrent.atomic
提供了 int 和 long 的包裹類,可以用來實現這種原子操作,而無需使用同步。
Java AtomicInteger 範例
這是更新後的程式,它將始終將計數值輸出為8,因為 AtomicInteger
方法 incrementAndGet()
會原子性地將當前值增加一。
package com.journaldev.concurrency;
import java.util.concurrent.atomic.AtomicInteger;
public class JavaAtomic {
public static void main(String[] args) throws InterruptedException {
ProcessingThread pt = new ProcessingThread();
Thread t1 = new Thread(pt, "t1");
t1.start();
Thread t2 = new Thread(pt, "t2");
t2.start();
t1.join();
t2.join();
System.out.println("Processing count=" + pt.getCount());
}
}
class ProcessingThread implements Runnable {
private AtomicInteger count = new AtomicInteger();
@Override
public void run() {
for (int i = 1; i < 5; i++) {
processSomething(i);
count.incrementAndGet();
}
}
public int getCount() {
return this.count.get();
}
private void processSomething(int i) {
// 處理某些工作
try {
Thread.sleep(i * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
使用 Concurrency 類進行原子操作的好處是我們不需要擔心同步。這提高了代碼的可讀性,並且減少了錯誤的機會。同時,原子操作的並發類被認為比涉及鎖定資源的同步更有效率。
Source:
https://www.digitalocean.com/community/tutorials/atomicinteger-java