1. 線程同步以及線程調(diào)度相關(guān)的方法
- wait():使一個(gè)線程處于等待(阻塞)狀態(tài),并且釋放所持有的對(duì)象的鎖闲勺;
- sleep():使一個(gè)正在運(yùn)行的線程處于睡眠狀態(tài),是一個(gè)靜態(tài)方法笼踩,調(diào)用此方法要處理InterruptedException異常;
- notify():?jiǎn)拘岩粋€(gè)處于等待狀態(tài)的線程绑蔫,當(dāng)然在調(diào)用此方法的時(shí)候,并不能確切的喚醒某一個(gè)等待狀態(tài)的線程泵额,而是由JVM確定喚醒哪個(gè)線程配深,而且與優(yōu)先級(jí)無(wú)關(guān);
- notityAll():?jiǎn)拘阉刑幱诘却隣顟B(tài)的線程嫁盲,該方法并不是將對(duì)象的鎖給所有線程篓叶,而是讓它們競(jìng)爭(zhēng),只有獲得鎖的線程才能進(jìn)入就緒狀態(tài)羞秤;
2. 進(jìn)程和線程的區(qū)別
進(jìn)程是執(zhí)行著的應(yīng)用程序缸托,而線程是進(jìn)程內(nèi)部的一個(gè)執(zhí)行序列。一個(gè)進(jìn)程可以有多個(gè)線程瘾蛋。
另一種回答:
線程是進(jìn)程的一個(gè)單元嗦董,也是進(jìn)程內(nèi)的可調(diào)度實(shí)體。區(qū)別就是:1瘦黑、進(jìn)程內(nèi)的線程共享地址空間,進(jìn)程則自己獨(dú)立的地址空間奇唤。2幸斥、進(jìn)程是資源分配和擁有的單位,同一個(gè)進(jìn)程內(nèi)的線程共享進(jìn)程資源咬扇。3甲葬、線程是處理器調(diào)度的基本單位。4懈贺、兩者均可并發(fā)執(zhí)行经窖。
3. 實(shí)現(xiàn)線程有哪幾種方式?啟動(dòng)線程調(diào)用什么方法梭灿?
Java中實(shí)現(xiàn)線程有兩種方式:第一種是繼承Thread画侣,第二種是實(shí)現(xiàn)Runnable接口。啟動(dòng)線程用start()方法堡妒。
4. 請(qǐng)說(shuō)出你所知道的線程同步的方法配乱。
wait():使一個(gè)線程處于等待狀態(tài),并且釋放所持有的對(duì)象的lock皮迟。
sleep():使一個(gè)正在運(yùn)行的線程處于睡眠狀態(tài)搬泥,是一個(gè)靜態(tài)方法,調(diào)用此方法要捕捉InterruptedException異常伏尼。
notify():喚醒一個(gè)處于等待狀態(tài)的線程忿檩,注意的是在調(diào)用此方法的時(shí)候,并不能確切的喚醒某一個(gè)等待狀態(tài)的線程爆阶,而是由JVM確定喚醒哪個(gè)線程燥透,而且不是按優(yōu)先級(jí)沙咏。
notityAll():喚醒所有處入等待狀態(tài)的線程,注意并不是給所有喚醒線程一個(gè)對(duì)象的鎖兽掰,而是讓它們競(jìng)爭(zhēng)芭碍。
5. sleep() 和wait() 有什么區(qū)別?
sleep是線程類(lèi)(Thread)的方法,導(dǎo)致此線程暫停執(zhí)行指定時(shí)間孽尽,把執(zhí)行機(jī)會(huì)給其他線程窖壕,但是監(jiān)控狀態(tài)依然保持,到時(shí)后會(huì)自動(dòng)恢復(fù)杉女。調(diào)用sleep不會(huì)釋放對(duì)象鎖瞻讽。
? ? wait是Object類(lèi)的方法,對(duì)此對(duì)象調(diào)用wait方法導(dǎo)致本線程放棄對(duì)象鎖熏挎,進(jìn)入等待此對(duì)象的等待鎖定池速勇,只有針對(duì)此對(duì)象發(fā)出notify方法(或notifyAll)后本線程才進(jìn)入對(duì)象鎖定池準(zhǔn)備獲得對(duì)象鎖進(jìn)入運(yùn)行狀態(tài)。
6. 創(chuàng)建線程有幾種方式
創(chuàng)建線程有以下幾種方式:
? 繼承Thread類(lèi)
? 實(shí)現(xiàn)Runnable接口
? 應(yīng)用程序可以使用Executor框架來(lái)創(chuàng)建線程池
實(shí)現(xiàn)Runnable接口這種方式更受歡迎坎拐,因?yàn)檫@不需要繼承Thread類(lèi)烦磁。在已經(jīng)繼承了別的類(lèi)的情況下,這需要多繼承(而Java不支持多繼承)哼勇,只能實(shí)現(xiàn)接口都伪。同時(shí),線程池也是非常高效的积担,很容易實(shí)現(xiàn)和使用陨晶。
7. synchronized關(guān)鍵字的用法,優(yōu)缺點(diǎn)
答:java關(guān)鍵字帝璧,當(dāng)它用來(lái)修飾一個(gè)方法或者代碼塊的時(shí)候先誉,能夠保證在同一時(shí)刻最多只有一個(gè)線程執(zhí)行該代碼段的代碼;
synchronized修飾的方法或者對(duì)象的烁,只能以同步的方式執(zhí)行褐耳,會(huì)引起性能問(wèn)題;無(wú)法中斷一個(gè)正在等候獲得鎖的線程撮躁,也無(wú)法通過(guò)投票獲得鎖漱病;一個(gè)優(yōu)先級(jí)高的線程等待一個(gè)優(yōu)先級(jí)低的線程釋放鎖會(huì)導(dǎo)致優(yōu)先級(jí)倒置,引起性能風(fēng)險(xiǎn)把曼;
8. Thread 類(lèi)中的start() 和 run() 方法有什么區(qū)別杨帽?
start()方法被用來(lái)啟動(dòng)新創(chuàng)建的線程,而且start()內(nèi)部 調(diào)用了run()方法嗤军,這和直接調(diào)用run()方法的效果不一樣注盈。當(dāng)你調(diào)用run()方法的時(shí)候,只會(huì)是在原來(lái)的線程中調(diào)用叙赚,沒(méi)有新的線程啟 動(dòng)老客,start()方法才會(huì)啟動(dòng)新線程僚饭。
9. Java中的volatile 變量是什么?
volatile是一個(gè)特殊的修飾符胧砰,只有成員變量才能使用它鳍鸵。在Java并發(fā)程序缺少同步類(lèi)的情況下,多線程對(duì)成員變量的操作對(duì)其它線程是透明的尉间。volatile變量可以保證下一個(gè)讀取操作會(huì)在前一個(gè)寫(xiě)操作之后發(fā)生偿乖,就是上一題的volatile變量規(guī)則。
10. Java中notify 和 notifyAll有什么區(qū)別哲嘲?
這又是一個(gè)刁鉆的問(wèn)題贪薪,因?yàn)槎嗑€程可以等待單監(jiān)控鎖,Java API 的設(shè)計(jì)人員提供了一些方法當(dāng)?shù)却龡l件改變的時(shí)候通知它們眠副,但是這些方法沒(méi)有完全實(shí)現(xiàn)画切。notify()方法不能喚醒某個(gè)具體的線程,所以只有一個(gè)線程在等 待的時(shí)候它才有用武之地囱怕。而notifyAll()喚醒所有線程并允許他們爭(zhēng)奪鎖確保了至少有一個(gè)線程能繼續(xù)運(yùn)行霍弹。
11. 為什么wait, notify 和 notifyAll這些方法不在thread類(lèi)里面?
JAVA提供的鎖是對(duì)象級(jí)的而不是線程級(jí)的娃弓,每個(gè)對(duì)象都有鎖庞萍,通 過(guò)線程獲得。如果線程需要等待某些鎖那么調(diào)用對(duì)象中的wait()方法就有意義了忘闻。如果wait()方法定義在Thread類(lèi)中,線程正在等待的是哪個(gè)鎖 就不明顯了恋博。簡(jiǎn)單的說(shuō)齐佳,
由于wait,notify和notifyAll都是鎖級(jí)別的操作债沮,所以把他們定義在Object類(lèi)中因?yàn)殒i屬于對(duì)象炼吴。
12. 為什么wait和notify方法要在同步塊中調(diào)用?
主要是因?yàn)镴ava API強(qiáng)制要求這樣做疫衩,如果你不這么做硅蹦,你的代碼會(huì)拋出IllegalMonitorStateException異常。還有一個(gè)原因是為了避免wait和notify之間產(chǎn)生競(jìng)態(tài)條件闷煤。
13. Java中的同步集合與并發(fā)集合有什么區(qū)別童芹?
同步集合與并發(fā)集合都為多線程和并發(fā)提供了合適的線程安全的集合,不過(guò)并發(fā)集合的可擴(kuò)展性更高鲤拿。在Java1.5之前程序員們只有同步集合來(lái)用且在 多線程并發(fā)的時(shí)候會(huì)導(dǎo)致?tīng)?zhēng)用假褪,阻礙了系統(tǒng)的擴(kuò)展性。Java5介紹了并發(fā)集合像ConcurrentHashMap近顷,不僅提供線程安全還用鎖分離和內(nèi)部分 區(qū)等現(xiàn)代技術(shù)提高了可擴(kuò)展性生音。
14. Java中堆和棧有什么不同宁否?
棧是一種線形集合,其添加和刪除元素的操作應(yīng)在同一段完成缀遍。棧按照后進(jìn)先出的方式進(jìn)行處理慕匠。
堆是棧的一個(gè)組成元素
15. 什么是線程池? 為什么要使用它域醇?
創(chuàng)建線程要花費(fèi)昂貴的資源和時(shí)間台谊,如果任務(wù)來(lái)了才創(chuàng)建線程那么響應(yīng)時(shí)間會(huì)變長(zhǎng),而且一個(gè)進(jìn)程能創(chuàng)建的線程數(shù)有限歹苦。為了避免這些問(wèn)題青伤,在程序啟動(dòng)的時(shí) 候就創(chuàng)建若干線程來(lái)響應(yīng)處理,它們被稱為線程池殴瘦,里面的線程叫工作線程狠角。從JDK1.5開(kāi)始,Java API提供了Executor框架讓你可以創(chuàng)建不同的線程池蚪腋。比如單線程池丰歌,每次處理一個(gè)任務(wù);數(shù)目固定的線程池或者是緩存線程池(一個(gè)適合很多生存期短 的任務(wù)的程序的可擴(kuò)展線程池)屉凯。
16. Java多線程中調(diào)用wait() 和 sleep()方法有什么不同立帖?
Java程序中wait 和 sleep都會(huì)造成某種形式的暫停,它們可以滿足不同的需要悠砚。wait()方法用于線程間通信晓勇,如果等待條件為真且其它線程被喚醒時(shí)它會(huì)釋放鎖,而 sleep()方法僅僅釋放CPU資源或者讓當(dāng)前線程停止執(zhí)行一段時(shí)間灌旧,但不會(huì)釋放鎖绑咱。
17. 同步方法和同步代碼塊的區(qū)別是什么?
同步方法就是在方法前加關(guān)鍵字synchronized枢泰,然后被同步的方法一次只能有一個(gè)線程進(jìn)入描融,其他線程等待。
而同步代碼塊則是在方法內(nèi)部使用大括號(hào)使得一個(gè)代碼塊得到同步衡蚂。同步塊會(huì)有一個(gè)鎖定的“對(duì)象”窿克。同步代碼塊的同步范圍更加準(zhǔn)確。
18. 同步和異步有何異同毛甲,在什么情況下分別使用他們年叮?舉例說(shuō)明。
如果數(shù)據(jù)將在線程間共享玻募。例如正在寫(xiě)的數(shù)據(jù)以后可能被另一個(gè)線程讀到谋右,或者正在讀的數(shù)據(jù)可能已經(jīng)被另一個(gè)線程寫(xiě)過(guò)了,那么這些數(shù)據(jù)就是共享數(shù)據(jù)补箍,必須進(jìn)行同步存取改执。
當(dāng)應(yīng)用程序在對(duì)象上調(diào)用了一個(gè)需要花費(fèi)很長(zhǎng)時(shí)間來(lái)執(zhí)行的方法啸蜜,并且不希望讓程序等待方法的返回時(shí),就應(yīng)該使用異步編程辈挂,在很多情況下采用異步途徑往往更有效率衬横。
19. 什么是Java優(yōu)先級(jí)隊(duì)列(Priority Queue)?
PriorityQueue是一個(gè)基于優(yōu)先級(jí)堆的無(wú)界隊(duì)列终蒂,它的元素是按照自然順序(natural order)排序的蜂林。在創(chuàng)建的時(shí)候,我們可以給它提供一個(gè)負(fù)責(zé)給元素排序的比較器拇泣。PriorityQueue不允許null值噪叙,因?yàn)樗麄儧](méi)有自然順序,或者說(shuō)他們沒(méi)有任何的相關(guān)聯(lián)的比較器霉翔。最后睁蕾,PriorityQueue不是線程安全的,入隊(duì)和出隊(duì)的時(shí)間復(fù)雜度是O(log(n))债朵。
20. 什么是同步?
同步用來(lái)控制共享資源在多個(gè)線程間的訪問(wèn)子眶,以保證同一時(shí)間內(nèi)只有一個(gè)線程能訪問(wèn)到這個(gè)資源。在非同步保護(hù)的多線程程序里面序芦,一個(gè)線程正在修改一個(gè)共享變量的時(shí)候臭杰,可能有另一個(gè)線程也在使用或者更新它的值。同步避免了臟數(shù)據(jù)的產(chǎn)生谚中。