1.在java中守護(hù)線(xiàn)程和本地線(xiàn)程區(qū)別?
java中的線(xiàn)程分為兩種:守護(hù)線(xiàn)程(Daemon)和用戶(hù)線(xiàn)程(User)。
任何線(xiàn)程都可以設(shè)置為守護(hù)線(xiàn)程和用戶(hù)線(xiàn)程,通過(guò)方法Thread.setDaemon(bool on);true則把該線(xiàn)程設(shè)置為守護(hù)線(xiàn)程,反之則為用戶(hù)線(xiàn)程。Thread.setDaemon()必須在Thread.start()之前調(diào)用,否則運(yùn)行時(shí)會(huì)拋出異常。
兩者的區(qū)別:
虛擬機(jī)(JVM)何時(shí)離開(kāi),Daemon是為其他線(xiàn)程提供服務(wù),如果全部的User Thread已經(jīng)撤離,Daemon沒(méi)有可服務(wù)的線(xiàn)程,JVM撤離。也可以理解為守護(hù)線(xiàn)程是JVM自動(dòng)創(chuàng)建的線(xiàn)程(但不一定),用戶(hù)線(xiàn)程是程序創(chuàng)建的線(xiàn)程;比如JVM的垃圾回收線(xiàn)程是一個(gè)守護(hù)線(xiàn)程,當(dāng)所有線(xiàn)程已經(jīng)撤離,不再產(chǎn)生垃圾,守護(hù)線(xiàn)程自然就沒(méi)事可干了,當(dāng)垃圾回收線(xiàn)程是Java虛擬機(jī)上僅剩的線(xiàn)程時(shí),Java虛擬機(jī)會(huì)自動(dòng)離開(kāi)。
擴(kuò)展:Thread Dump打印出來(lái)的線(xiàn)程信息,含有daemon字樣的線(xiàn)程即為守護(hù)進(jìn)程,可能會(huì)有:服務(wù)守護(hù)進(jìn)程、編譯守護(hù)進(jìn)程、windows下的監(jiān)聽(tīng)Ctrl+break的守護(hù)進(jìn)程、Finalizer守護(hù)進(jìn)程、引用處理守護(hù)進(jìn)程、GC守護(hù)進(jìn)程。
2.線(xiàn)程與進(jìn)程的區(qū)別?
進(jìn)程是操作系統(tǒng)分配資源的最小單元,線(xiàn)程是操作系統(tǒng)調(diào)度的最小單元。
一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線(xiàn)程。
3.什么是多線(xiàn)程中的上下文切換?
多線(xiàn)程會(huì)共同使用一組計(jì)算機(jī)上的CPU,而線(xiàn)程數(shù)大于給程序分配的CPU數(shù)量時(shí),為了讓各個(gè)線(xiàn)程都有執(zhí)行的機(jī)會(huì),就需要輪轉(zhuǎn)使用CPU。不同的線(xiàn)程切換使用CPU發(fā)生的切換數(shù)據(jù)等就是上下文切換。
4.死鎖與活鎖的區(qū)別,死鎖與饑餓的區(qū)別?
死鎖:是指兩個(gè)或兩個(gè)以上的進(jìn)程(或線(xiàn)程)在執(zhí)行過(guò)程中,因爭(zhēng)奪資源而造成的一種互相等待的現(xiàn)象,若無(wú)外力作用,它們都將無(wú)法推進(jìn)下去。
產(chǎn)生死鎖的必要條件:
互斥條件:所謂互斥就是進(jìn)程在某一時(shí)間內(nèi)獨(dú)占資源。
請(qǐng)求與保持條件:一個(gè)進(jìn)程因請(qǐng)求資源而阻塞時(shí),對(duì)已獲得的資源保持不放。
不剝奪條件:進(jìn)程已獲得資源,在末使用完之前,不能強(qiáng)行剝奪。
循環(huán)等待條件:若干進(jìn)程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。
活鎖:任務(wù)或者執(zhí)行者沒(méi)有被阻塞,由于某些條件沒(méi)有滿(mǎn)足,導(dǎo)致一直重復(fù)嘗試、失敗、嘗試、失敗。
活鎖和死鎖的區(qū)別在于,處于活鎖的實(shí)體是在不斷的改變狀態(tài),所謂的“活”,而處于死鎖的實(shí)體表現(xiàn)為等待;活鎖有可能自行解開(kāi),死鎖則不能。
饑餓:一個(gè)或者多個(gè)線(xiàn)程因?yàn)榉N種原因無(wú)法獲得所需要的資源,導(dǎo)致一直無(wú)法執(zhí)行的狀態(tài)。
Java中導(dǎo)致饑餓的原因:
高優(yōu)先級(jí)線(xiàn)程吞噬所有的低優(yōu)先級(jí)線(xiàn)程的CPU時(shí)間。
線(xiàn)程被永久堵塞在一個(gè)等待進(jìn)入同步塊的狀態(tài),因?yàn)槠渌€(xiàn)程總是能在它之前持續(xù)地對(duì)該同步塊進(jìn)行訪問(wèn)。
線(xiàn)程在等待一個(gè)本身也處于永久等待完成的對(duì)象(比如調(diào)用這個(gè)對(duì)象的wait方法),因?yàn)槠渌€(xiàn)程總是被持續(xù)地獲得喚醒。
5.Java中用到的線(xiàn)程調(diào)度算法是什么?
采用時(shí)間片輪轉(zhuǎn)的方式。可以設(shè)置線(xiàn)程的優(yōu)先級(jí),會(huì)映射到下層的系統(tǒng)上面的優(yōu)先級(jí)上,如非特別需要,盡量不要用,防止線(xiàn)程饑餓。
6.什么是線(xiàn)程組,為什么在Java中不推薦使用?
ThreadGroup類(lèi),可以把線(xiàn)程歸屬到某一個(gè)線(xiàn)程組中,線(xiàn)程組中可以有線(xiàn)程對(duì)象,也可以有線(xiàn)程組,組中還可以有線(xiàn)程,這樣的組織結(jié)構(gòu)有點(diǎn)類(lèi)似于樹(shù)的形式。
為什么不推薦使用?因?yàn)橛泻芏嗟陌踩[患吧,如果需要使用,推薦使用線(xiàn)程池。
7.為什么使用Executor框架?
每次執(zhí)行任務(wù)創(chuàng)建線(xiàn)程new Thread()比較消耗性能,創(chuàng)建一個(gè)線(xiàn)程是比較耗時(shí)、耗資源的。
調(diào)用new Thread()創(chuàng)建的線(xiàn)程缺乏管理,被稱(chēng)為野線(xiàn)程,而且可以無(wú)限制的創(chuàng)建,線(xiàn)程之間的相互競(jìng)爭(zhēng)會(huì)導(dǎo)致過(guò)多占用系統(tǒng)資源而導(dǎo)致系統(tǒng)癱瘓,還有線(xiàn)程之間的頻繁交替也會(huì)消耗很多系統(tǒng)資源。
接使用new Thread()啟動(dòng)的線(xiàn)程不利于擴(kuò)展,比如定時(shí)執(zhí)行、定期執(zhí)行、定時(shí)定期執(zhí)行、線(xiàn)程中斷等都不便實(shí)現(xiàn)。
8.在Java中Executor和Executors的區(qū)別?
Executors工具類(lèi)的不同方法按照我們的需求創(chuàng)建了不同的線(xiàn)程池,來(lái)滿(mǎn)足業(yè)務(wù)的需求。
Executor接口對(duì)象能執(zhí)行我們的線(xiàn)程任務(wù)。
ExecutorService接口繼承了Executor接口并進(jìn)行了擴(kuò)展,提供了更多的方法我們能獲得任務(wù)執(zhí)行的狀態(tài)并且可以獲取任務(wù)的返回值。
使用ThreadPoolExecutor可以創(chuàng)建自定義線(xiàn)程池。
Future表示異步計(jì)算的結(jié)果,他提供了檢查計(jì)算是否完成的方法,以等待計(jì)算的完成,并可以使用get()方法獲取計(jì)算的結(jié)果。
9.什么是原子操作?
原子操作是指一個(gè)不受其他操作影響的操作任務(wù)單元。原子操作是在多線(xiàn)程環(huán)境下避免數(shù)據(jù)不一致必須的手段。
處理器使用基于對(duì)緩存加鎖或總線(xiàn)加鎖的方式來(lái)實(shí)現(xiàn)多處理器之間的原子操作。
在Java中可以通過(guò)鎖和循環(huán)CAS的方式來(lái)實(shí)現(xiàn)原子操作。CAS操作——Compare&Set,或是Compare&Swap,現(xiàn)在幾乎所有的CPU指令都支持CAS的原子操作。
int++并不是一個(gè)原子操作,所以當(dāng)一個(gè)線(xiàn)程讀取它的值并加1時(shí),另外一個(gè)線(xiàn)程有可能會(huì)讀到之前的值,這就會(huì)引發(fā)錯(cuò)誤。
為了解決這個(gè)問(wèn)題,必須保證增加操作是原子的,在JDK1.5之前我們可以使用同步技術(shù)來(lái)做到這一點(diǎn)。到JDK1.5,
java.util.concurrent.atomic包提供了int和long類(lèi)型的原子包裝類(lèi),它們可以自動(dòng)的保證對(duì)于他們的操作是原子的并且不需要使用同步。
java.util.concurrent這個(gè)包里面提供了一組原子類(lèi)。其基本的特性就是在多線(xiàn)程環(huán)境下,當(dāng)有多個(gè)線(xiàn)程同時(shí)執(zhí)行這些類(lèi)的實(shí)例包含的方法時(shí),具有排他性,即當(dāng)某個(gè)線(xiàn)程進(jìn)入方法,執(zhí)行其中的指令時(shí),不會(huì)被其他線(xiàn)程打斷,而別的線(xiàn)程就像自旋鎖一樣,一直等到該方法執(zhí)行完成,才由JVM從等待隊(duì)列中選擇一個(gè)另一個(gè)線(xiàn)程進(jìn)入,這只是一種邏輯上的理解。
10.Java Concurrency API中的Lock接口是什么?對(duì)比同步它有什么優(yōu)勢(shì)?
Lock接口比同步方法和同步塊提供了更具擴(kuò)展性的鎖操作。
他們?cè)试S更靈活的結(jié)構(gòu),可以具有完全不同的性質(zhì),并且可以支持多個(gè)相關(guān)類(lèi)的條件對(duì)象。
它的優(yōu)勢(shì)有:
可以使鎖更公平
可以使線(xiàn)程在等待鎖的時(shí)候響應(yīng)中斷
可以讓線(xiàn)程嘗試獲取鎖,并在無(wú)法獲取鎖的時(shí)候立即返回或者等待一段時(shí)間
可以在不同的范圍,以不同的順序獲取和釋放鎖
整體上來(lái)說(shuō)Lock是synchronized的擴(kuò)展版,Lock提供了無(wú)條件的、可輪詢(xún)的、定時(shí)的、可中斷的、可多條件隊(duì)列的鎖操作。另外Lock的實(shí)現(xiàn)類(lèi)基本都支持非公平鎖和公平鎖,synchronized只支持非公平鎖,當(dāng)然,在大部分情況下,非公平鎖是高效的選擇。
以上就是深圳達(dá)內(nèi)教育java培訓(xùn)機(jī)構(gòu)的小編針對(duì)“2020年經(jīng)典Java編程練習(xí)題及答案”的內(nèi)容進(jìn)行的回答,希望對(duì)大家有所幫助,如有疑問(wèn),請(qǐng)?jiān)诰€(xiàn)咨詢(xún),有專(zhuān)業(yè)老師隨時(shí)為你服務(wù)。