東莞 包裝制品 東莞網(wǎng)站建設(shè)產(chǎn)品市場(chǎng)推廣方案范文
目錄
- 面試題一:并行和并發(fā)有什么區(qū)別?
- 面試題二:線程和進(jìn)程的區(qū)別?
- 追問(wèn):守護(hù)線程是什么?
- 面試題三:創(chuàng)建線程的幾種方式?
- 1. 繼承 Thread 類創(chuàng)建線程,重寫 run() 方法
- 2. 實(shí)現(xiàn) Runnable 接口創(chuàng)建線程,實(shí)現(xiàn) run() 方法
- 追問(wèn):Runnable 和 Callable 有什么區(qū)別?
- 補(bǔ)充:FutureTask
面試題一:并行和并發(fā)有什么區(qū)別?
- 并行是指兩個(gè)或者多個(gè)事件在同?時(shí)刻發(fā)?;而并發(fā)是指兩個(gè)或多個(gè)事件在同?時(shí)間間隔發(fā)?;
- 并行是在不同實(shí)體上的多個(gè)事件,并發(fā)是在同?實(shí)體上的多個(gè)事件;
- 在?臺(tái)處理器上“同時(shí)”處理多個(gè)任務(wù),在多臺(tái)處理器上同時(shí)處理多個(gè)任務(wù)。如 Hadoop 分布式集群。所以并發(fā)編程的目標(biāo)是充分的利?處理器的每?個(gè)核,以達(dá)到最?的處理性能。
面試題二:線程和進(jìn)程的區(qū)別?
進(jìn)程:是程序運(yùn)行和資源分配的基本單位,?個(gè)程序至少有?個(gè)進(jìn)程,?個(gè)進(jìn)程至少有?個(gè)線程。進(jìn)程在執(zhí)行過(guò)程中擁有獨(dú)立的內(nèi)存單元,而多個(gè)線程共享內(nèi)存資源,減少切換次數(shù),從而效率更?。
- 舉個(gè)例子,當(dāng)我們雙擊桌面的圖標(biāo)時(shí),系統(tǒng)會(huì)將對(duì)應(yīng)的程序加載進(jìn)內(nèi)存,程序?qū)?huì)占用一部分內(nèi)存用以執(zhí)行操作。進(jìn)入到內(nèi)存的程序即為進(jìn)程(一個(gè)應(yīng)用程序可以同時(shí)運(yùn)行多個(gè)進(jìn)程)。當(dāng)使用任務(wù)管理器關(guān)閉程序時(shí)(比如LOL),系統(tǒng)又會(huì)將程序從內(nèi)存中清除,此時(shí)進(jìn)程結(jié)束。如圖:一個(gè) LOL 進(jìn)程。
-
線程:是進(jìn)程的?個(gè)實(shí)體,是 cpu 調(diào)度和分派的基本單位,是比程序更小的能獨(dú)立運(yùn)行的基本單位。同?進(jìn)程中的多個(gè)線程之間可以并發(fā)執(zhí)行。
需要注意的是,Java 本身并不能創(chuàng)造線程,因?yàn)榫€程其實(shí)是操作系統(tǒng)的一種資源,它由操作系統(tǒng)管理。我們一般說(shuō)“Java 支持多線程”,指的就是 Java 可以調(diào)用系統(tǒng)資源創(chuàng)建多線程。
追問(wèn):守護(hù)線程是什么?
用戶線程:我們平常創(chuàng)建的普通線程。
守護(hù)線程(即 Daemon thread),是個(gè)服務(wù)線程,用來(lái)服務(wù)于用戶線程,準(zhǔn)確地來(lái)說(shuō)就是服務(wù)其他的線程。 在JVM中,所有非守護(hù)線程都執(zhí)行完畢后,無(wú)論有沒(méi)有守護(hù)線程,虛擬機(jī)都會(huì)自動(dòng)退出。
守護(hù)線程怎么使用:使用很簡(jiǎn)單,只是在調(diào)用start()方法前,調(diào)用 setDaemon(true) 把該線程標(biāo)記為守護(hù)線程。
- 如何檢查一個(gè)線程是守護(hù)線程還是用戶線程:使用isDaemon()方法。
- Java垃圾回收線程就是一個(gè)典型的守護(hù)線程,因?yàn)槲覀兊睦厥帐且粋€(gè)一直需要運(yùn)行的機(jī)制,但是當(dāng)沒(méi)有用戶線程的時(shí)候,也就不需要垃圾回收線程了,守護(hù)線程剛好滿足這樣的需求。
面試題三:創(chuàng)建線程的幾種方式?
1. 繼承 Thread 類創(chuàng)建線程,重寫 run() 方法
public class ThreadDemo1 extends Thread {public static void main(String[] args) {// ThreadDemo 繼承了Thread類,并重寫run()ThreadDemo t = new ThreadDemo();// 開(kāi)啟線程:t線程得到CPU執(zhí)行權(quán)后會(huì)執(zhí)行run()中的代碼t.start();}@Overridepublic void run() {System.out.println("Thread is running");}
}
2. 實(shí)現(xiàn) Runnable 接口創(chuàng)建線程,實(shí)現(xiàn) run() 方法
public class ThreadDemo2 implements Runnable{public static void main(String[] args) {// ThreadDemo2實(shí)現(xiàn)Runnable接口,并實(shí)現(xiàn)run()ThreadDemo2 target = new ThreadDemo2();// 調(diào)用Thread構(gòu)造方法,傳入TreadDemo2的實(shí)例對(duì)象,創(chuàng)建線程對(duì)象Thread t = new Thread(target);// 開(kāi)啟線程:t線程得到CPU執(zhí)行權(quán)后會(huì)執(zhí)行run()中的代碼t.start();}public void run() {System.out.println("Thread is running");}
}
- 通過(guò) Callable 和 Future 創(chuàng)建線程;
- 通過(guò) 線程池 創(chuàng)建線程。
追問(wèn):Runnable 和 Callable 有什么區(qū)別?
- Runnable 接口中的 run() 方法的返回值是 void,它做的事情只是純粹地去執(zhí)行 run() 方法中的代碼而已; run方法不可以拋出異常。
- Callable 接口中的 call() 方法是有返回值的,是?個(gè)泛型,和 Future、FutureTask 配合可以用來(lái)獲取異步執(zhí)行的結(jié)果。call方法可以拋出異常。
補(bǔ)充:FutureTask
未來(lái)的任務(wù),用它就干一件事,異步調(diào)用 main 方法就像一個(gè)冰糖葫蘆,一個(gè)個(gè)方法由 main 串起來(lái)。
但解決不了一個(gè)問(wèn)題:正常調(diào)用掛起堵塞問(wèn)題。
例子:
- 老師上著課,口渴了,去買水不合適,講課線程繼續(xù),我可以單起個(gè)線程找班長(zhǎng)幫忙買水,水買回來(lái)了放桌上,我需要的時(shí)候再去get。
- 4個(gè)同學(xué),A 算1+到20,B 算21+到30,C 算31*到40,D算41+到50,是不是 C 的計(jì)算量有點(diǎn)大啊,FutureTask 單起個(gè)線程給 C 計(jì)算,我先匯總 ABD,最后等 C 計(jì)算完了再匯總 C,拿到最終結(jié)果。
- 高考:會(huì)做的先做,不會(huì)的放在后面做 。
原理:在主線程中需要執(zhí)行比較耗時(shí)的操作時(shí),但又不想阻塞主線程時(shí),可以把這些作業(yè)交給 Future 對(duì)象在后臺(tái)完成,當(dāng)主線程將來(lái)需要時(shí),就可以通過(guò) Future 對(duì)象獲得后臺(tái)作業(yè)的計(jì)算結(jié)果或者執(zhí)行狀態(tài)。 一般 FutureTask 多用于耗時(shí)的計(jì)算,主線程可以在完成自己的任務(wù)后,再去獲取結(jié)果。 僅在計(jì)算完成時(shí)才能檢索結(jié)果;如果計(jì)算尚未完成,則阻塞 get 方法。一旦計(jì)算完成,就不能再重新開(kāi)始或取消計(jì)算。get方法而獲取結(jié)果只有在計(jì)算完成時(shí)獲取,否則會(huì)一直阻塞直到任務(wù)轉(zhuǎn)入完成狀態(tài),然后會(huì)返回結(jié)果或者拋出異常。 只計(jì)算一次 get 方法放到最后。
public class CallableDemo {public static void main(String[] args) {FutureTask<Integer> futureTask = new FutureTask<Integer>(() -> {System.out.println(Thread.currentThread().getName() + " come");return 1024;});new Thread(futureTask,"AAA").start();try {System.out.println(futureTask.get());} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}
}運(yùn)行結(jié)果:
AAA come
1024