原創(chuàng)
1 背景
在學(xué)習(xí)并發(fā)的時(shí)候看到了ConcurrentLinkedQueue隊(duì)列的源碼,剛開始的時(shí)候是看網(wǎng)上的帖子,然后就到IDE里邊看源碼,發(fā)現(xiàn)offer()方法在1.7版的時(shí)候有過修改。

樓主的問題不是整個(gè)方法,而是其中的一截代碼“(t != (t = tail))”,有點(diǎn)發(fā)暈,t是個(gè)引用,而修改引用的時(shí)候不是都修改嗎?怎么還會(huì)判斷是否相等呢 ?
2 為了解決這個(gè)問題,寫個(gè)測(cè)試方法。如下:
publicclassReferTest {
publicstaticvoidmain(String[] args) {
ReferTest a =newReferTest();
booleanb= (a != (a =newReferTest()));
}
}
答案:b= true。
說明 a != a,這個(gè)就更暈了。在度娘和谷歌上都查不到什么有用的資料,關(guān)鍵是不好描述,引用不等于引用?
再往下樓主就猜測(cè)了,引用的東西一般都和棧有關(guān),就想看看方法的字節(jié)碼指令。使用javap命令解釋了方法的字節(jié)碼指令。

有用的方法看main方法的指令,樓主沒有接觸過字節(jié)碼指令,所以找個(gè)指令集學(xué)學(xué)了一下。在這里解釋下指令的意義,在這里記錄一下。

注意引用1是在命令8的時(shí)候加載的a的值,而引用2是新的引用,為什么出現(xiàn)這種情況,原因是if_acmpeq指令是比較兩個(gè)棧頂?shù)闹凳欠褚粯印?br>
所以在"!="號(hào)的兩端的值需要加載到棧頂,而右邊是一個(gè)表達(dá)式,所以先加載左邊的值到棧頂然后再去執(zhí)行右邊的表達(dá)式,表達(dá)式的結(jié)果放入棧頂,這個(gè)時(shí)候a引用1先加載,而表達(dá)式的結(jié)果會(huì)改變a變量的值,但是不會(huì)改變棧頂?shù)闹怠?/p>
所以就出現(xiàn)不一致的情況了。
同理,通過這個(gè)方式可以判斷對(duì)應(yīng)的引用是否改變了。
ps:跟同事講解的時(shí)候,又分析了 i=i++ 、 i=++i、i= i+1的字節(jié)碼,發(fā)現(xiàn) i++ 使用的是iinc的命令,而i=i+1使用的是iadd指令。
