進程和線程的區(qū)別是什么?
進程是執(zhí)行著的應(yīng)用程序,而線程是進程內(nèi)部的一個執(zhí)行序列。一個進程可以有多個線程。線程又叫做輕量級進程。
線程與進程的區(qū)別歸納:
a.地址空間和其它資源:進程間相互獨立,同一進程的各線程間共享。某進程內(nèi)的線程在其它進程不可見。
b.通信:進程間通信IPC,線程間可以直接讀寫進程數(shù)據(jù)段(如全局變量)來進行通信——需要進程同步和互斥手段的輔助,以保證數(shù)據(jù)的一致性。
c.調(diào)度和切換:線程上下文切換比進程上下文切換要快得多。
d.在多線程OS中,進程不是一個可執(zhí)行的實體。
創(chuàng)建線程有幾種不同的方式?你喜歡哪一種?為什么?
有4種方式可以用來創(chuàng)建線程:
繼承Thread類
實現(xiàn)Runnable接口(函數(shù)式接口模式代表)
應(yīng)用程序可以使用Executor框架來創(chuàng)建線程池
實現(xiàn)Runnable接口這種方式更受歡迎,因為這不需要繼承Thread類。在應(yīng)用設(shè)計中已經(jīng)繼承了別的對象的情況下,這需要多繼承(而Java不支持多繼承),只能實現(xiàn)接口。同時,線程池也是非常高效的,很容易實現(xiàn)和使用。
還有一種方式是實現(xiàn)Callable接口
概括的解釋下線程的幾種可用狀態(tài)。
1.新建(new):新創(chuàng)建了一個線程對象。
2.可運行(runnable
):線程對象創(chuàng)建后,其他線程(比如main線程)調(diào)用了該對象的start()方法。該狀態(tài)的線程位于可運行線程池中,等待被線程調(diào)度選中,獲取cpu的使用權(quán)。
3.運行(running):可運行狀態(tài)(runnable)的線程獲得了cpu時間片(timeslice),執(zhí)行程序代碼。
4.阻塞(block):阻塞狀態(tài)是指線程因為某種原因放棄了cpu使用權(quán),也即讓出了cpu timeslice,暫時停止運行。直到線程進入可運行(runnable
)狀態(tài),才有機會再次獲得cpu timeslice轉(zhuǎn)到運行(running)狀態(tài)。阻塞的情況分三種:
(一).等待阻塞:運行(running)的線程執(zhí)行o.wait()方法,JVM會把該線程放入等待隊列(waitting queue)中。
(二).同步阻塞:運行(running)的線程在獲取對象的同步鎖時,若該同步鎖被別的線程占用,則JVM會把該線程放入鎖池(lock pool)中。
(三).其他阻塞:運行(running)的線程執(zhí)行Thread.sleep(long
ms)或t.join
()方法,或者發(fā)出了I/O請求時,JVM會把該線程置為阻塞狀態(tài)。當sleep()狀態(tài)超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉(zhuǎn)入可運行(runnable
)狀態(tài)。
5.死亡(dead):線程run()、main()方法執(zhí)行結(jié)束,或者因異常退出了run()方法,則該線程結(jié)束生命周期。死亡的線程不可再次復(fù)生。
同步方法和同步代碼塊的區(qū)別是什么?
區(qū)別:
同步方法默認用this或者當前類class對象作為鎖;
同步代碼塊可以選擇以什么來加鎖,比同步方法要更細顆粒度,我們可以選擇只同步會發(fā)生同步問題的部分代碼而不是整個方法;
同步方法使用關(guān)鍵字
synchronized修飾方法,而同步代碼塊主要是修飾需要進行同步的代碼,用synchronized(object){代碼內(nèi)容}進行修飾;
在監(jiān)視器(Monitor)內(nèi)部,是如何做線程同步的?程序應(yīng)該做哪種級別的同步?
監(jiān)視器和鎖在Java虛擬機中是一塊使用的。監(jiān)視器監(jiān)視一塊同步代碼塊,確保一次只有一個線程執(zhí)行同步代碼塊。每一個監(jiān)視器都和一個對象引用相關(guān)聯(lián)。線程在獲取鎖之前不允許執(zhí)行同步代碼。
什么是死鎖(deadlock)?
所謂死鎖是指多個進程因競爭資源而造成的一種僵局(互相等待),若無外力作用,這些進程都將無法向前推進。死鎖產(chǎn)生的4個必要條件:
互斥條件:進程要求對所分配的資源(如打印機)進行排他性控制,即在一段時間內(nèi)某
資源僅為一個進程所占有。此時若有其他進程請求該資源,則請求進程只能等待。
不剝奪條件:進程所獲得的資源在未使用完畢之前,不能被其他進程強行奪走,即只能
由獲得該資源的進程自己來釋放(只能是主動釋放)。
請求和保持條件:進程已經(jīng)保持了至少一個資源,但又提出了新的資源請求,而該資源
已被其他進程占有,此時請求進程被阻塞,但對自己已獲得的資源保持不放。
循環(huán)等待條件:存在一種進程資源的循環(huán)等待鏈,鏈中每一個進程已獲得的資源同時被
鏈中下一個進程所請求。
如何確保N個線程可以訪問N個資源同時又不導(dǎo)致死鎖?
使用多線程的時候,一種非常簡單的避免死鎖的方式就是:指定獲取鎖的順序,并強制線程按照指定的順序獲取鎖。因此,如果所有的線程都是以同樣的順序加鎖和釋放鎖,就不會出現(xiàn)死鎖了。
Java集合類框架的基本接口有哪些?
集合類接口指定了一組叫做元素的對象。集合類接口的每一種具體的實現(xiàn)類都可以選擇以它自己的方式對元素進行保存和排序。有的集合類允許重復(fù)的鍵,有些不允許。
Java集合類提供了一套設(shè)計良好的支持對一組對象進行操作的接口和類。Java集合類里面最基本的接口有:
Collection:代表一組對象,每一個對象都是它的子元素。
Set:不包含重復(fù)元素的Collection。
List:有順序的collection,并且可以包含重復(fù)元素。
Map:可以把鍵(key)映射到值(value)的對象,鍵不能重復(fù)。
為什么集合類沒有實現(xiàn)Cloneable和Serializable接口?
克隆(cloning)或者是序列化(serialization)的語義和含義是跟具體的實現(xiàn)相關(guān)的。因此,應(yīng)該由集合類的具體實現(xiàn)來決定如何被克隆或者是序列化。
以上就是天津卓眾教育java培訓機構(gòu)的小編針對“Java基礎(chǔ)50道經(jīng)典練習題及答案”的內(nèi)容進行的回答,希望對大家有所幫助,如有疑問,請在線咨詢,有專業(yè)老師隨時為你服務(wù)。