破除java神話之原子操作都是線程安全的
更新時(shí)間: 2007-06-04 13:22:31來源: 粵嵌教育瀏覽量:596
java中原子操作是線程安全的論調(diào)經(jīng)常被提到。根據(jù)定義,原子操作是不會(huì)被打斷地的操作,因此被認(rèn)為是線程安全的。實(shí)際上有一些原子操作不一定是線程安全的。
這個(gè)問題出現(xiàn)的原因是盡量減少在代碼中同步關(guān)鍵字。同步會(huì)損害性能,雖然這個(gè)損失因JVM不同而不同。另外,在現(xiàn)代的JVM中,同步的性能正在逐步提高。盡管如此,使用同步仍然是有性能代價(jià)的,并且程序員永遠(yuǎn)會(huì)盡力提高他們的代碼的效率,因此這個(gè)問題就延續(xù)了下來。
在java中,32位或者更少位數(shù)的賦值是原子的。在一個(gè)32位的硬件平臺(tái)上,除了double和long型的其它原始類型通常都是使用32位進(jìn)行表示,而double和long通常使用64位表示。另外,對(duì)象引用使用本機(jī)指針實(shí)現(xiàn),通常也是32位的。對(duì)這些32位的類型的操作是原子的。
這些原始類型通常使用32位或者64位表示,這又引入了另一個(gè)小小的神話:原始類型的大小是由語言保證的。這是不對(duì)的。java語言保證的是原始類型的表數(shù)范圍而非JVM中的存儲(chǔ)大小。因此,int型總是有相同的表數(shù)范圍。在一個(gè)JVM上可能使用32位實(shí)現(xiàn),而在另一個(gè)JVM上可能是64位的。在此再次強(qiáng)調(diào):在所有平臺(tái)上被保證的是表數(shù)范圍,32位以及更小的值的操作是原子的。
那么,原子操作在什么情況下不是線程安全的?主要的一點(diǎn)是他們也許確實(shí)是線程安全的,但是這沒有被保證!java線程允許線程在自己的內(nèi)存區(qū)保存變量的副本。允許線程使用本地的私有拷貝進(jìn)行工作而非每次都使用主存的值是為了提高性能。考慮下面的類:
class RealTimeClock
{
private int clkID;
public int clockID()
{
return clkID;
}
public void setClockID(int id)
{
clkID = id;
}
//...
}
現(xiàn)在考慮RealTimeClock的一個(gè)實(shí)例以及兩個(gè)線程同時(shí)調(diào)用setClockID和clockID,并發(fā)生以下的事件序列:
T1 調(diào)用setClockID(5)
T1將5放入自己的私有工作內(nèi)存
T2調(diào)用setClockID(10)
T2將10放入自己的私有工作內(nèi)存
T1調(diào)用clockID,它返回5
5是從T1的私有工作內(nèi)存返回的
對(duì)clockI的調(diào)用應(yīng)該返回10,因?yàn)檫@是被T2設(shè)置的,然而返回的是5,因?yàn)樽x寫操作是對(duì)私有工作內(nèi)存的而非主存。賦值操作當(dāng)然是原子的,但是因?yàn)镴VM允許這種行為,因此線程安全不是一定的,同時(shí),JVM的這種行為也不是被保證的。
兩個(gè)線程擁有自己的私有拷貝而不和主存一致。如果這種行為出現(xiàn),那么私有本機(jī)變量和主存一致必須在以下兩個(gè)條件下:
1、變量使用volatile聲明
2、被訪問的變量處于同步方法或者同步塊中
如果變量被聲明為volatile,在每次訪問時(shí)都會(huì)和主存一致。這個(gè)一致性是由java語言保證的,并且是原子的,即使是64位的值。(注意很多JVM沒有正確的實(shí)現(xiàn)volatile關(guān)鍵字。你可以在www.javasoft.com找到更多的信息。)另外,如果變量在同步方法或者同步塊中被訪問,當(dāng)在方法或者塊的入口處獲得鎖以及方法或者塊退出時(shí)釋放鎖是變量被同步。
使用任何一種方法都可以保證ClockID返回10,也就是正確的值。變量訪問的頻度不同則你的選擇的性能不同。如果你更新很多變量,那么使用volatile可能比使用同步更慢。記住,如果變量被聲明為volatile,那么在每次訪問時(shí)都會(huì)和主存一致。與此對(duì)照,使用同步時(shí),變量只在獲得鎖和釋放鎖的時(shí)候和主存一致。但是同步使得代碼有較少的并發(fā)性。
如果你更新很多變量并且不想有每次訪問都和主存進(jìn)行同步的損失或者你因?yàn)槠渌脑蛳肱懦l(fā)性時(shí)可以考慮使用同步。
粵嵌動(dòng)態(tài)
推薦閱讀
- ·Linux字符設(shè)備驅(qū)動(dòng)框架解析:file_operations的核心作用與實(shí)現(xiàn)
- ·廣東朝歌數(shù)碼科技股份有限公司專場(chǎng)招聘會(huì)
- ·深化產(chǎn)教融合,共筑技能人才培養(yǎng)新生態(tài) —— 廣州華立學(xué)院到訪粵嵌從化校區(qū)為深化產(chǎn)教
- ·校企合作新突破 | 粵嵌科技與三亞學(xué)院共探產(chǎn)教融合新路徑
- ·粵嵌科技入選國(guó)家級(jí)職業(yè)數(shù)字展館聯(lián)合建設(shè)單位,賦能計(jì)算機(jī)程序設(shè)計(jì)員高技能人才培養(yǎng)
- ·嵌入式實(shí)時(shí)操作系統(tǒng)的性能優(yōu)化與實(shí)現(xiàn)路徑
- ·校企攜手賦能教育!粵嵌科技助力海南科技職業(yè)大學(xué)探索 AGI 時(shí)代教學(xué)新范式
- ·嵌入式系統(tǒng)中的低功耗設(shè)計(jì)策略與實(shí)現(xiàn)路徑
- ·深圳市軒宇軟件開發(fā)有限公司專場(chǎng)招聘會(huì)
- ·嵌入式系統(tǒng)中的代碼空間優(yōu)化:策略與實(shí)踐