每個(gè)JAVA對(duì)象都有一把所, 當(dāng)有多個(gè)線程同時(shí)訪問共享資源的時(shí)候, 需要Synchronize 來控制安全性, synchronize 分 synchronize 方法 和synchronize快,使用synchronize塊時(shí), 一定要顯示的獲得該對(duì)象的鎖(如synchronize(object))而方法則不需要。
?JAVA 的內(nèi)存模型是對(duì)每一個(gè)進(jìn)程有一個(gè)主內(nèi)存, 每個(gè)線程有自己的內(nèi)存, 他們從主內(nèi)存中取數(shù)據(jù), 然后計(jì)算, 再存入主內(nèi)存中。
?并發(fā)問題如下:如果多個(gè)線程同事操作同一數(shù)據(jù), A線程從主內(nèi)存中取的I的值為1, 然后進(jìn)行加1操作, 這時(shí)B線程也取I的值, 進(jìn)行加2操作, 然后A存入2到主內(nèi)存中, B也存入, 這樣就覆蓋了A的值(同數(shù)據(jù)庫中的并發(fā)問題一樣)。
解決辦法是用synchronize, 如用synchronized(I)。被synchronize 修飾的方法(塊)把以下三步操作當(dāng)成一個(gè)原子操作:取數(shù)據(jù), 操作數(shù)據(jù), 存數(shù)據(jù)。 我們知道原子操作是不可以被打斷的, 所以其保證了數(shù)據(jù)一致性, 這樣同一時(shí)間只有一個(gè)線程再執(zhí)行, 對(duì)性能有一定的影響。這也是synchronize的第二個(gè)作用:保證統(tǒng)一時(shí)間只有一個(gè)線程再運(yùn)行。 當(dāng)實(shí)現(xiàn)SOCKET連接的時(shí)候經(jīng)常用到.
?JAVA中規(guī)定對(duì)非FLOAT, LONG的原始類型的取和存操作為原子操作。 其實(shí)就是對(duì)一個(gè)字(32位)的取,存位原始操作, 因?yàn)镕LOAT, LONG為兩個(gè)字節(jié)的長(zhǎng)度, 所以其取, 存為非原子操作。 如果想把他們也變?yōu)樵硬僮鳎?可以用VOLATILE關(guān)鍵字來修飾。