1 Java中的volatile關(guān)鍵是什么作用爬立?怎樣使用它谭网?在Java中它跟synchronized方法有什么不同歧胁?
自從Java 5和Java內(nèi)存模型改變以后,基于volatile關(guān)鍵字的線程問題越來越流行修噪。應(yīng)該準(zhǔn)備好回答關(guān)于volatile變量怎樣在并發(fā)環(huán)境中確保可見性路媚。
volatile關(guān)鍵字的作用是:保證變量的可見性黄琼。
在java內(nèi)存結(jié)構(gòu)中,每個(gè)線程都是有自己獨(dú)立的內(nèi)存空間(此處指的線程棧)整慎。當(dāng)需要對(duì)一個(gè)共享變量操作時(shí)脏款,線程會(huì)將這個(gè)數(shù)據(jù)從主存空間復(fù)制到自己的獨(dú)立空間內(nèi)進(jìn)行操作,然后在某個(gè)時(shí)刻將修改后的值刷新到主存空間裤园。這個(gè)中間時(shí)間就會(huì)發(fā)生許多奇奇怪怪的線程安全問題了撤师,volatile就出來了,它保證讀取數(shù)據(jù)時(shí)只從主存空間讀取拧揽,修改數(shù)據(jù)直接修改到主存空間中去剃盾,這樣就保證了這個(gè)變量對(duì)多個(gè)操作線程的可見性了。換句話說强法,被volatile修飾的變量万俗,能保證該變量的 單次讀或者單次寫 操作是原子的。
但是線程安全是兩方面需要的 原子性(指的是多條操作)和可見性饮怯。volatile只能保證可見性闰歪,synchronized是兩個(gè)均保證的。
volatile輕量級(jí)蓖墅,只能修飾變量库倘;synchronized重量級(jí),還可修飾方法论矾。
volatile不會(huì)造成線程的阻塞教翩,而synchronized可能會(huì)造成線程的阻塞。
2 為什么我們調(diào)用start()方法時(shí)會(huì)執(zhí)行run()方法贪壳,為什么我們不能直接調(diào)用run()方法饱亿?
這是另一個(gè)非常經(jīng)典的java多線程面試問題。這也是我剛開始寫線程程序時(shí)候的困惑∪蜓ィ現(xiàn)在這個(gè)問題通常在電話面試或者是在初中級(jí)Java面試的第一輪被問到彪笼。這個(gè)問題的回答應(yīng)該是這樣的,當(dāng)你調(diào)用start()方法時(shí)你將創(chuàng)建新的線程蚂且,并且執(zhí)行在run()方法里的代碼配猫。但是如果你直接調(diào)用run()方法,它不會(huì)創(chuàng)建新的線程也不會(huì)執(zhí)行調(diào)用線程的代碼杏死。
3?什么是不可變對(duì)象泵肄,它對(duì)寫并發(fā)應(yīng)用有什么幫助捆交?
另一個(gè)多線程經(jīng)典面試問題,并不直接跟線程有關(guān)腐巢,但間接幫助很多品追。這個(gè)java面試問題可以變的非常棘手,如果他要求你寫一個(gè)不可變對(duì)象系忙,或者問你為什么String是不可變的诵盼。
immutable Objects(不可變對(duì)象)就是那些一旦被創(chuàng)建惠豺,它們的狀態(tài)就不能被改變的Objects银还,每次對(duì)他們的改變都是產(chǎn)生了新的immutable的對(duì)象,而mutable Objects(可變對(duì)象)就是那些創(chuàng)建后洁墙,狀態(tài)可以被改變的Objects.
如何在Java中寫出Immutable的類蛹疯?
1. immutable對(duì)象的狀態(tài)在創(chuàng)建之后就不能發(fā)生改變,任何對(duì)它的改變都應(yīng)該產(chǎn)生一個(gè)新的對(duì)象热监。
2. immutable類的所有的屬性都應(yīng)該是final的捺弦。
3. 對(duì)象必須被正確的創(chuàng)建,比如:對(duì)象引用在對(duì)象創(chuàng)建過程中不能泄露(leak)孝扛。
4. 對(duì)象應(yīng)該是final的列吼,以此來限制子類繼承父類,以避免子類改變了父類的immutable特性苦始。
5. 如果類中包含mutable類對(duì)象寞钥,那么返回給客戶端的時(shí)候,返回該對(duì)象的一個(gè)拷貝陌选,而不是該對(duì)象本身(該條可以歸為第一條中的一個(gè)特例)
使用Immutable類的好處:
1. Immutable對(duì)象是線程安全的理郑,可以不用被synchronize就在并發(fā)環(huán)境中共享
2.Immutable對(duì)象簡(jiǎn)化了程序開發(fā),因?yàn)樗鼰o需使用額外的鎖機(jī)制就可以在線程間共享
3. Immutable對(duì)象提高了程序的性能咨油,因?yàn)樗鼫p少了synchroinzed的使用
4. Immutable對(duì)象是可以被重復(fù)使用的您炉,你可以將它們緩存起來重復(fù)使用,就像字符串字面量和整型數(shù)字一樣役电。你可以使用靜態(tài)工廠方法來提供類似于valueOf()這樣的方法赚爵,它可以從緩存中返回一個(gè)已經(jīng)存在的Immutable對(duì)象,而不是重新創(chuàng)建一個(gè)法瑟。