effective java第66條,同步訪問共享變量的一個(gè)例子
例如
public class VolatileTest {
private static boolean testBool;
public static void main(String[] args) throws InterruptedException {
Thread test = new Thread(new Runnable(){
public void run(){
int i = 0;
while(!testBool){
i++;
}
}
});
test.start();
TimeUnit.SECONDS.sleep(1);
testBool = true;
}
}
書中說虛擬機(jī)會(huì)將代碼優(yōu)化hoisting
if(!testBool){
while(true) i++
}
而導(dǎo)致該進(jìn)程操作無法停止
可以使用sync關(guān)鍵字同步讀寫testBool變量,從而達(dá)想要的通信效果
也可以使用volatile修飾符修飾testBool,該修飾符會(huì)強(qiáng)制線程復(fù)制的共享變量值一直為共享池中的最新值。
但是如果JVM仍然進(jìn)行hoisting優(yōu)化,效果應(yīng)該是不正確的。而實(shí)際效果是正確的??赡苁莢olatile修飾符強(qiáng)行終止了JVM優(yōu)化。
volatile并不能實(shí)現(xiàn)同步互斥,只是讓線程一直獲取最新的共享內(nèi)容,只能保證對單次讀/寫的原子性,像i++這種操作是讀和寫兩次操作,讀取i,對i+1,寫入i。
測試發(fā)現(xiàn),在i++后執(zhí)行一個(gè)System.out.println("i" + i);內(nèi)容也會(huì)發(fā)生VM沒有進(jìn)行優(yōu)化操作,代碼在主線程執(zhí)行完賦值就終止了。
而且翻閱網(wǎng)絡(luò)上的文章,發(fā)現(xiàn)VM使用client模式也不會(huì)復(fù)現(xiàn)優(yōu)化后的場景,只有server模式VM才可以復(fù)現(xiàn)