詳細介紹Java中的Atomic包所使用的程式碼分享
引言
Java從JDK1.5開始提供了java.util.concurrent.atomic包,方便程式設計師在多執行緒環境下,無鎖定的進行原子操作。原子變數的底層使用了處理器提供的原子指令,但是不同的CPU架構可能提供的原子指令不一樣,也有可能需要某種形式的內部鎖,所以該方法不能絕對保證執行緒不被阻塞。
Atomic套件介紹
在Atomic套件裡一共有12個類,四種原子更新方式,分別是原子更新基本類型,原子更新數組,原子更新引用和原子更新字段。 Atomic包裡的類別基本上都是使用Unsafe實現的包裝類別。
原子更新基本類型類別
用於透過原子的方式更新基本類型,Atomic套件提供了以下三個類別:
AtomicBoolean:原子更新布林類型。
AtomicInteger:原子更新整數型。
AtomicLong:原子更新長整型。
AtomicInteger的常用方法如下:
int addAndGet(int delta) :以原子方式將輸入的數值與實例中的值( AtomicInteger裡的value)相加,並傳回結果
boolean compareAndSet(int expect, int update) :如果輸入的數值等於預期值,則以原子方式將該值設為輸入的值。
int getAndIncrement():以原子方式將目前值加1,注意:這裡傳回的是自增前的值。
void lazySet(int newValue):最終會設定成newValue,使用lazySet設定值後,可能會導致其他執行緒在之後的一小段時間內還是可以讀到舊的值。
int getAndSet(int newValue):以原子方式設定為newValue的值,並傳回舊值。
AtomicInteger範例程式碼如下:
import java.util.concurrent.atomic.AtomicInteger; public class AtomicIntegerTest { static AtomicInteger ai = new AtomicInteger(1); public static void main(String[] args) { System.out.println(ai.getAndIncrement()); System.out.println(ai.get()); } }
輸出
1 2
餐後甜點
Atomic套件提供了三種基本類型的原子更新,但是Java的基本型別裡還有char,float和double等。那麼問題來了,如何原子的更新其他的基本型別呢? Atomic套件裡的類別基本上都是使用Unsafe實現的,讓我們一起看下Unsafe的源碼,發現Unsafe只提供了三種CAS方法,compareAndSwapObject,compareAndSwapInt和compareAndSwapLong,再看AtomicBoolean源碼,發現其是先把Boolean轉換成整型,再使用compareAndSwapInt進行CAS,所以原子更新double也可以用類似的想法來實現。
原子更新陣列類別
透過原子的方式更新陣列裡的某個元素,Atomic套件提供了以下三個類別:
- ##AtomicIntegerArray :原子更新整數陣列裡的元素。
- AtomicLongArray:原子更新長整數陣列裡的元素。
- AtomicReferenceArray:原子更新引用型別陣列裡的元素。
- int addAndGet(int i, int delta):以原子方式將輸入值與陣列中索引i的元素相加。
- boolean compareAndSet(int i, int expect, int update):如果目前值等於預期值,則以原子方式將陣列位置i的元素設定成update值。
public class AtomicIntegerArrayTest { static int[] value = new int[] { 1, 2 }; static AtomicIntegerArray ai = new AtomicIntegerArray(value); public static void main(String[] args) { ai.getAndSet(0, 3); System.out.println(ai.get(0)); System.out.println(value[0]); } }
3 1
建構方法傳遞進去,然後AtomicIntegerArray會將目前陣列複製一份,所以當AtomicIntegerArray對內部的陣列元素進行修改時,不會影響到傳入的陣列。
原子更新引用型別原子更新基本型別的AtomicInteger,只能更新一個變量,如果要原子的更新多個變量,就需要使用這個原子更新引用型別提供的類別。 Atomic套件提供了以下三個類別:- AtomicReference:原子更新引用類型。
- AtomicReferenceFieldUpdater:原子更新參考類型裡的欄位。
- AtomicMarkableReference:原子更新帶有標記位的參考類型。可以原子的更新一個布林類型的標記位和引用型別。建構方法是AtomicMarkableReference(V initialRef, boolean initialMark)
public class AtomicReferenceTest { public static AtomicReference<user> atomicUserRef = new AtomicReference</user><user>(); public static void main(String[] args) { User user = new User("conan", 15); atomicUserRef.set(user); User updateUser = new User("Shinichi", 17); atomicUserRef.compareAndSet(user, updateUser); System.out.println(atomicUserRef.get().getName()); System.out.println(atomicUserRef.get().getOld()); } static class User { private String name; private int old; public User(String name, int old) { this.name = name; this.old = old; } public String getName() { return name; } public int getOld() { return old; } } }
Shinichi 17
- AtomicIntegerFieldUpdater:原子更新整型的字段的更新器。
- AtomicLongFieldUpdater:原子更新長整數欄位的更新器。
AtomicStampedReference:原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于原子的更数据和数据的版本号,可以解决使用CAS进行原子更新时,可能出现的ABA问题。
原子更新字段类都是抽象类,每次使用都时候必须使用静态方法newUpdater创建一个更新器。原子更新类的字段的必须使用public Volatile修饰符。AtomicIntegerFieldUpdater的例子代码如下:
public class AtomicIntegerFieldUpdaterTest { private static AtomicIntegerFieldUpdater<User> a = AtomicIntegerFieldUpdater .newUpdater(User.class, "old"); public static void main(String[] args) { User conan = new User("conan", 10); System.out.println(a.getAndIncrement(conan)); System.out.println(a.get(conan)); } public static class User { private String name; public volatile int old; public User(String name, int old) { this.name = name; this.old = old; } public String getName() { return name; } public int getOld() { return old; } } }
输出
10 11
以上是詳細介紹Java中的Atomic包所使用的程式碼分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。

PHP適用於Web開發和內容管理系統,Python適合數據科學、機器學習和自動化腳本。 1.PHP在構建快速、可擴展的網站和應用程序方面表現出色,常用於WordPress等CMS。 2.Python在數據科學和機器學習領域表現卓越,擁有豐富的庫如NumPy和TensorFlow。
