java交换integer_Java比较和交换语义和性能
Java中比較和交換的語義是什么?即,AtomicInteger公正的比較和交換方法是保證不同線程之間對原子整數實例的特定內存位置的有序訪問,還是保證對內存中所有位置的有序訪問,即,它的行為就像是易失的(內存圍欄)。
從文檔:
weakCompareAndSet原子地讀取和有條件地寫入變量,但不會在排序之前創建任何事件,因此,對于除的目標以外的任何變量的先前或后續讀取和寫入不提供任何保證weakCompareAndSet。
compareAndSet以及所有其他讀取和更新操作(例如,getAndIncrement具有讀取和寫入易失性變量的內存效應)。
從API文檔可以明顯看出它的compareAndSet作用就像是一個volatile變量。但是,weakCompareAndSet應該只是更改其特定的內存位置。因此,如果該內存位置是單個處理器的高速緩存專用的,weakCompareAndSet則應該比常規內存快得多compareAndSet。
我之所以這樣問是因為我已經通過運行從1到8的threadnum不同線程對以下方法進行了基準測試(代碼是用靜態編譯的JVM語言Scala編寫的,但是其含義和字節碼翻譯對于在這種情況下是Java的-
這段簡短的片段應該很清楚):threadnum``totalwork=1e9
val atomic_cnt = new AtomicInteger(0)
val atomic_tlocal_cnt = new java.lang.ThreadLocal[AtomicInteger] {
override def initialValue = new AtomicInteger(0)
}
def loop_atomic_tlocal_cas = {
var i = 0
val until = totalwork / threadnum
val acnt = atomic_tlocal_cnt.get
while (i < until) {
i += 1
acnt.compareAndSet(i - 1, i)
}
acnt.get + i
}
def loop_atomic_weakcas = {
var i = 0
val until = totalwork / threadnum
val acnt = atomic_cnt
while (i < until) {
i += 1
acnt.weakCompareAndSet(i - 1, i)
}
acnt.get + i
}
def loop_atomic_tlocal_weakcas = {
var i = 0
val until = totalwork / threadnum
val acnt = atomic_tlocal_cnt.get
while (i < until) {
i += 1
acnt.weakCompareAndSet(i - 1, i)
}
acnt.get + i
}
在具有4個雙2.8 GHz內核和2.67 GHz 4核i7處理器的AMD上。JVM是Sun Server Hotspot JVM
1.6。結果表明沒有性能差異。
規格:AMD 8220 4x雙核@ 2.8 GHz
測試名稱:loop_atomic_tlocal_cas
線程數:1
運行時間:(顯示最后3個)7504.562 7502.817 7504.626(平均= 7415.637分鐘= 7147.628最大= 7504.886)
線程數:2
運行時間:(顯示最后3個)3751.553 3752.589 3751.519(平均= 3713.5513分鐘= 3574.708最大= 3752.949)
線程數:4
運行時間:(顯示最后3個)1890.055 1889.813 1890.047(平均= 2065.7207分鐘= 1804.652最大= 3755.852)
線程數:8
運行時間:(顯示最后3個)960.12 989.453 970.842(平均= 1058.8776分鐘= 940.492最大= 1893.127)
測試名稱:loop_atomic_weakcas
線程數:1
運行時間:(顯示最后3個)7325.425 7057.03 7325.407(平均= 7231.8682分鐘= 7057.03最大= 7325.45)
線程數:2
運行時間:(顯示最后3個)3663.21 3665.838 3533.406(平均= 3607.2149分鐘= 3529.177最大= 3665.838)
線程數:4
運行時間:(顯示最后3個)3664.163 1831.979 1835.07(平均= 2014.2086分鐘= 1797.997最大值= 3664.163)
線程數:8
運行時間:(顯示最后3個)940.504 928.467 921.376(平均= 943.665分鐘= 919.985最大= 997.681)
測試名稱:loop_atomic_tlocal_weakcas
線程數:1
運行時間:(顯示最后3個)7502.876 7502.857 7502.933(平均= 7414.8132分鐘= 7145.869最大= 7502.933)
線程數:2
運行時間:(顯示最后3個)3752.623 3751.53 3752.434(平均= 3710.1782分鐘= 3574.398最大= 3752.623)
線程數:4
運行時間:(顯示最后3個)1876.723 1881.069 1876.538(平均= 4110.4221分鐘= 1804.62最大= 12467.351)
線程數:8
運行時間:(顯示最后3個)959.329 1010.53 969.767(平均= 1072.8444分鐘= 959.329最大= 1880.049)
規格:Intel i7四核@ 2.67 GHz
測試名稱:loop_atomic_tlocal_cas
線程數:1
運行時間:(顯示最后3個)8138.3175 8130.0044 8130.1535(平均= 8119.2888分鐘= 8049.6497最大=
8150.1950)
線程數:2
運行時間:(顯示最后3個)4067.7399 4067.5403 4068.3747(平均= 4059.6344分鐘= 4026.2739最大=
4068.5455)
線程數:4
運行時間:(顯示最后3個)2033.4389 2033.2695 2033.2918(平均= 2030.5825分鐘= 2017.6880最大=
2035.0352)
測試名稱:loop_atomic_weakcas
線程數:1
運行時間:(顯示最后3個)8130.5620 8129.9963 8132.3382(平均= 8114.0052分鐘= 8042.0742最大=
8132.8542)
線程數:2
運行時間:(顯示最后3個)4066.9559 4067.0414 4067.2080(平均= 4086.0608分鐘= 4023.6822最大=
4335.1791)
線程數:4
運行時間:(顯示最后3個)2034.6084 2169.8127 2034.5625(平均= 2047.7025分鐘= 2032.8131最大=
2169.8127)
測試名稱:loop_atomic_tlocal_weakcas
線程數:1
運行時間:(顯示最后3個)8132.5267 8132.0299 8132.2415(平均= 8114.9328分鐘= 8043.3674最大=
8134.0418)
線程數:2
運行時間:(顯示最后3個)4066.5924 4066.5797 4066.6519(平均= 4059.1911分鐘= 4025.0703最大=
4066.8547)
線程數:4
運行時間:(顯示最后3個)2033.2614 2035.5754 2036.9110(平均= 2033.2958分鐘= 2023.5082最大=
2038.8750)
雖然上面示例中的線程局部變量有可能以相同的緩存行結尾,但在我看來,常規CAS及其弱版本之間沒有可觀察到的性能差異。
實際上,這可能意味著比較弱和交換作用就像完全成熟的內存屏障,即好像它是一個可變變量一樣。
問題:這個觀察正確嗎?另外,是否存在已知的體系結構或Java發行版,其弱比較和設置實際上更快?如果不是,首先使用弱CAS有什么好處?
總結
以上是生活随笔為你收集整理的java交换integer_Java比较和交换语义和性能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java文件流 m.jb51.net_L
- 下一篇: MySQL如何优雅的删除大表