阿里一面 —— 什么是多线程?
馬上就要到金三銀四佳季了,是找工作的好時候,小伙伴們一定要把握好時機,找到心儀的高薪工作。找工作就少不了面試,那我們從現(xiàn)在開始,多刷刷面試題,查缺補漏!!!
?
?
目錄
?什么是線程?線程和進程的區(qū)別??
?創(chuàng)建線程有幾種方式??
?Runnable和Callable的區(qū)別??
?如何啟動一個新線程、調(diào)用start和run方法的區(qū)別??
?線程有哪幾種狀態(tài)以及各種狀態(tài)之間的轉(zhuǎn)換??
?線程相關(guān)的基本方法??
?wait()和sleep()的區(qū)別??
?
?
?什么是線程?線程和進程的區(qū)別??
?
線程:是進程的一個實體,是 cpu 調(diào)度和分派的基本單位,是比進程更小的
可以獨立運行的基本單位。
進程:具有一定獨立功能的程序關(guān)于某個數(shù)據(jù)集合上的一次運行活動,是操作
系統(tǒng)進行資源分配和調(diào)度的一個獨立單位。
特點:線程的劃分尺度小于進程,這使多線程程序擁有高并發(fā)性,進程在運行
時各自內(nèi)存單元相互獨立,線程之間 內(nèi)存共享,這使多線程編程可以擁有更好
的性能和用戶體驗。
?創(chuàng)建線程有幾種方式??
1.繼承Thread類并重寫 run 方法創(chuàng)建線程,實現(xiàn)簡單但不可以繼承其他類
2.實現(xiàn)Runnable接口并重寫 run 方法。避免了單繼承局限性,編程更加靈活,實現(xiàn)解耦。
3..實現(xiàn) Callable接口并重寫 call 方法,創(chuàng)建線程。可以獲取線程執(zhí)行結(jié)果的返回值,并且可以拋出異常。
4.使用線程池創(chuàng)建(使用java.util.concurrent.Executor接口)
?Runnable和Callable的區(qū)別??
Runnable 接口 run 方法無返回值;Callable 接口 call 方法有返回值,支持泛型
Runnable 接口 run 方法只能拋出運行時異常,且無法捕獲處理;Callable 接口 call 方法允許拋出異常,可以獲取異常信息
?如何啟動一個新線程、調(diào)用start和run方法的區(qū)別??
線程對象調(diào)用run方法不開啟線程。僅是對象調(diào)用方法。
線程對象調(diào)用start開啟線程,并讓jvm調(diào)用run方法在開啟的線程中執(zhí)行
調(diào)用start方法可以啟動線程,并且使得線程進入就緒狀態(tài),而run方法只是thread的一個普通方法,還是在主線程中執(zhí)行。
?
?線程有哪幾種狀態(tài)以及各種狀態(tài)之間的轉(zhuǎn)換??
1. 第一是new->新建狀態(tài)。在生成線程對象,并沒有調(diào)用該對象的start方法,這是線程處于創(chuàng)建狀態(tài)。
2. 第二是Runnable->就緒狀態(tài)。當調(diào)用了線程對象的start方法之后,該線程就進入了就緒狀態(tài),但是此時線程調(diào)度程序還沒有把該線程設(shè)置為當前線程,此時處于就緒狀態(tài)。
3. 第三是Running->運行狀態(tài)。線程調(diào)度程序?qū)⑻幱诰途w狀態(tài)的線程設(shè)置為當前線程,此時線程就進入了運行狀態(tài),開始運行run函數(shù)當中的代碼。
4. 第四是阻塞狀態(tài)。阻塞狀態(tài)是線程因為某種原因放棄CPU使用權(quán),暫時停止運行。直到線程進入就緒狀態(tài),才有機會轉(zhuǎn)到運行狀態(tài)。阻塞的情況分三種:
(1)等待 – 通過調(diào)用線程的wait()?方法,讓線程等待某工作的完成。
(2)超時等待 – 通過調(diào)用線程的sleep()?或join()或發(fā)出了I/O請求時,線程會進入到阻塞狀態(tài)。當sleep()狀態(tài)超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉(zhuǎn)入就緒狀態(tài)。
(3)同步阻塞 – 線程在獲取synchronized同步鎖失敗(因為鎖被其它線程所占用),它會進入同步阻塞狀態(tài)。
5. 第五是dead->死亡狀態(tài): 線程執(zhí)行完了或者因異常退出了run()方法,該線程結(jié)束生命周期.
?線程相關(guān)的基本方法??
線程相關(guān)的基本方法有 wait,notify,notifyAll,sleep,join,yield 等
1.線程等待(wait)
調(diào)用該方法的線程進入 WAITING 狀態(tài),只有等待另外線程的通知或被中
斷才會返回,需要注意的是調(diào)用 wait()方法后,會釋放對象的鎖。因此,wait 方
法一般用在同步方法或同步代碼塊中。
2.線程睡眠(sleep)
sleep 導(dǎo)致當前線程休眠,與 wait 方法不同的是 sleep 不會釋放當前占
有的鎖,sleep(long)會導(dǎo)致線程進入 TIMED-WATING 狀態(tài),而 wait()方法
會導(dǎo)致當前線程進入 WATING 狀態(tài).
3.線程讓步(yield)
yield 會使當前線程讓出 CPU 執(zhí)行時間片,與其他線程一起重新競爭
CPU 時間片。一般情況下,優(yōu)先級高的線程有更大的可能性成功競爭得到 CPU
時間片,但這又不是絕對的,有的操作系統(tǒng)對 線程優(yōu)先級并不敏感。
4.線程中斷(interrupt)
中斷一個線程,其本意是給這個線程一個通知信號,會影響這個線程內(nèi)部的
一個中斷標識位。這個線程本身并不會因此而改變狀態(tài)(如阻塞,終止等)
5.Join 等待其他線程終止
join() 方法,等待其他線程終止,在當前線程中調(diào)用一個線程的 join() 方
法,則當前線程轉(zhuǎn)為阻塞狀態(tài),回到另一個線程結(jié)束,當前線程再由阻塞狀態(tài)變
為就緒狀態(tài),等待 cpu 的寵幸.
6.線程喚醒(notify)
Object 類中的 notify() 方法,喚醒在此對象監(jiān)視器上等待的單個線程,如
果所有線程都在此對象上等待,則會選擇喚醒其中一個線程,選擇是任意的,并
在對實現(xiàn)做出決定時發(fā)生,線程通過調(diào)用其中一個 wait() 方法,在對象的監(jiān)視
器上等待,直到當前的線程放棄此對象上的鎖定,才能繼續(xù)執(zhí)行被喚醒的線程,
被喚醒的線程將以常規(guī)方式與在該對象上主動同步的其他所有線程進行競爭。類
似的方法還有 notifyAll() ,喚醒再次監(jiān)視器上等待的所有線程。
?wait()和sleep()的區(qū)別??
1. 來自不同的類
wait():來自O(shè)bject類;
sleep():來自Thread類;
2. 關(guān)于鎖的釋放:
wait():在等待的過程中會釋放鎖;
sleep():在等待的過程中不會釋放鎖
3. 使用的范圍:
wait():必須在同步代碼塊中使用;
sleep():可以在任何地方使用;
4. 是否需要捕獲異常
wait():不需要捕獲異常;
sleep():需要捕獲異常;
?
總結(jié)
以上是生活随笔為你收集整理的阿里一面 —— 什么是多线程?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 官方预告相机光学创新成果:小米12 Ul
- 下一篇: C程序编译过程