日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

atomic java_在Java中添加@atomic操作

發(fā)布時(shí)間:2023/12/3 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 atomic java_在Java中添加@atomic操作 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

atomic java

總覽

原子操作如何在Java中工作,OpenJDK / Hotspot中是否存在可以轉(zhuǎn)換為原子的當(dāng)前替代方法。

反饋

在我以前的文章中, 對(duì)可變字段進(jìn)行原子操作。 有幾次指出,不管善意如何,“修復(fù)”先前的行為都不太可能繼續(xù)進(jìn)行。


替代方法是添加@atomic注釋。 這樣做的好處是僅適用于新代碼,而不會(huì)冒險(xiǎn)破壞舊代碼。

注意:故意使用小寫字母,因?yàn)樗?不*遵循當(dāng)前的編碼約定。

原子操作

任何帶有@atomic列出的字段都將使整個(gè)表達(dá)式具有原子性。 非易失性和非原子性變量可以在開(kāi)始時(shí)讀取,或者在表達(dá)式完成后進(jìn)行設(shè)置。 該表達(dá)式本身可能需要在某些平臺(tái),CAS操作或TSX上鎖定,具體取決于CPU技術(shù)。

如果僅讀取字段,或者也只寫入一個(gè)字段,則該字段與volatile相同。

原子布爾

當(dāng)前,AtomicBoolean使用4個(gè)字節(jié),外加一個(gè)對(duì)象標(biāo)頭,并帶有可能的填充(以及引用)。如果該字段是內(nèi)聯(lián)的,則可能看起來(lái)像這樣

@atomic boolean flag; // toggle the flag. this.flag = !this.flag;

但是如何運(yùn)作? 并非所有平臺(tái)都支持1字節(jié)原子操作,例如Unsafe確實(shí)具有1字節(jié)CAS操作。 這可以通過(guò)掩膜來(lái)完成。

// possible replacement. while(true) {int num = Unsafe.getUnsafe().getVolatileInt(this, FLAG_OFFSET & ~3); // word align the access.int value ^= 1 << ~(0xFF << (FLAG_OFFSET & 3) * 8) ;if (Unsafe.getUnsafe().compareAndSwapInt(this, FLAG_OFFSET & ~3, num, value))break; }

原子雙

不支持的類型是AtomicDouble,但這是AtomicLong的變體。 考慮這個(gè)例子。

@atomic double a = 1; volatile double b = 2;a += b;

今天如何實(shí)施?

while(true) {double _b = Unsafe.getUnsafe().getVolatileDouble(this, B_OFFSET);double _a = Unsafe.getUnsafe().getVolatileDouble(this, A_OFFSET);long aAsLong = Double.doubleToRawLongBits(_a);double _sum = _a + _b;long sumAsLong = Double.doubleToRawLongBits(_a);if (Unsafe.getUnsafe().compareAndSwapLong(this, A_OFFSET, aAsLong, sumAsLong))break; }

兩個(gè)原子場(chǎng)

使用Intel TSX,您可以將硬件事務(wù)包裝在多個(gè)字段中,但是如果沒(méi)有TSX,該事務(wù)仍可以完成而無(wú)需求助于鎖。

@atomic int a = 1, b = 2;a += b * (b % 2 == 0 ? 2 : 1);

如果字段在一起,仍然可以使用CAS來(lái)完成。 計(jì)劃執(zhí)行CAS2操作以檢查兩個(gè)64位值。 現(xiàn)在,此示例將使用兩個(gè)4字節(jié)值。

assert A_OFFSET + 4 == B_OFFSET; while(true) {long _ab = Unsafe.getUnsafe().getVolatileLong(this, A_OFFSET);int _a = getLowerInt(_ab);int _b = getHigherInt(_ab);int _sum = _a + _b * (_b % 2 == 0 ? 2 : 1);int _sum_ab = setLowerIntFor(_ab, _sum);if (Unsafe.getUnsafe().compareAndSwapLong(this, A_OFFSET, _ab, _sum_ab))break; }

注意:此操作可以原子方式處理a或b或兩者的更改。

原子參考

對(duì)不可變對(duì)象(例如BigDecimal)的常見(jiàn)用例操作。

@atomic BigDecimal a; BigDecimal b;a = a.add(b);

可以在具有CompressedOops或32位JVM的系統(tǒng)上以這種方式實(shí)現(xiàn)。

BigDecimal _b = this.b; while(true) {BigDecimal _a = (BigDecimal) Unsafe.getUnsafe().getVolatileObject(this, A_OFFSET);BigDecimal _sum = _a.add(_b);if (Unsafe.getUnsafe().compareAndSwapLong(this, A_OFFSET, _a, _sum))break; }

更復(fù)雜的例子

對(duì)于您的平臺(tái),總會(huì)有一些例子過(guò)于復(fù)雜。 在帶有TSX或HotSpot支持的系統(tǒng)的系統(tǒng)上,它們可能很好,但是您需要回退。

@atomic long a, b, c, d;a = (b = (c = d + 4) + 5 ) + 6;

當(dāng)前不支持此功能,因?yàn)樗谝粋€(gè)表達(dá)式中設(shè)置了多個(gè)long值。 但是,后退可能是使用現(xiàn)有的鎖。

synchronized(this) {a = (b = (c = d + 4) + 5 ) + 6; }

結(jié)論

通過(guò)添加注釋,我們可以將原子操作添加到常規(guī)字段,而無(wú)需更改語(yǔ)法。 這將是對(duì)語(yǔ)言的自然擴(kuò)展,而不會(huì)破壞向后的可比性。

翻譯自: https://www.javacodegeeks.com/2014/07/adding-atomic-operations-to-java.html

atomic java

總結(jié)

以上是生活随笔為你收集整理的atomic java_在Java中添加@atomic操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。