面试 -- 多线程( 一) -- 基础
1.什么是線程?什么是多線程?線程和進程的區(qū)別是什么?
答:
?(1)線程是進程的一個實體,是CPU調度和分派的基本單位,是比進程更小的能夠獨立運行的基本單位,同一進程中的多個線程之間可以并發(fā)執(zhí)行,能夠和同屬于一個進程的其他線程共享進程所擁有的所有資源。
?(2)多線程是指一個資源被多個線程同時調用而造成的多個線程同時執(zhí)行的情況。實際上多線程是一個線程執(zhí)行了一會之后其他線程又執(zhí)行一會,并不是同時執(zhí)行。使用多線程可以把長時間占用系統(tǒng)資源的任務放到后臺處理,提高了系統(tǒng)的運行速度。
?(3)線程和進程的區(qū)別:
①進程是操作系統(tǒng)資源分配的基本單位,線程是任務調度和執(zhí)行的基本單位;
②線程是進程的子集,是比進程更小的執(zhí)行單位,一個進程中可以有很多線程,每個線程并行執(zhí)行不同的任務。不同的進程使用不同的內存空間,所有線程共享同一塊內存空間和資源。各線程協(xié)同工作,負擔比進程小得多。
③進程是程序的一次執(zhí)行過程,是系統(tǒng)運行的基本單位。系統(tǒng)運行一個程序是進程從創(chuàng)建、運行到消亡的過程。一個進程就是一個執(zhí)行程序。進程會占用某些資源,如內存空間、CPU時間片、文件等。
另外:進程間的通信方式:管道、信號、消息隊列、共享內存、信號量、套接字
?
2.守護線程和用戶線程的區(qū)別。
答:Java中有兩類線程:User Thread(用戶線程)、Daemon Thread(守護線程)
用戶線程即運行在前臺的線程,而守護線程是運行在后臺的線程。守護線程的作用是為其他前臺線程的運行提供便利服務,并且在普通、非守護線程仍然運行時才需要,比如垃圾回收線程就是一個守護線程。
用戶線程和守護線程唯一不同之處就在于虛擬機的離開:如果 User Thread(用戶線程)已經(jīng)全部退出運行了,只剩下Daemon Thread(守護線程)存在了,虛擬機也就退出了。 因為沒有了被守護者,Daemon也就沒有工作可做了,也就沒有繼續(xù)運行程序的必要了。
守護線程并非只有虛擬機內部提供,用戶在編寫程序時也可以自己設置守護線程。用戶可以用Thread的setDaemon(true)方法設置當前線程為守護線程。
?
3.創(chuàng)建線程的幾種方式?
答:
(1)通過繼承Thread類,重寫run()方法來實現(xiàn);
(2)實現(xiàn)Runnable接口,并實現(xiàn)該接口的run()方法;
(3)實現(xiàn)Callable接口,重寫call方法;
實現(xiàn)Runnable接口可能更優(yōu)。原因:a、Java不支持多繼承,繼承了Thread類意味著不能繼承其他類;而實現(xiàn)Runnable接口還能繼承其他類;b、類可能只要求可執(zhí)行即可,因此繼承Thread類的開銷過大;
?
4.什么是死鎖?產生死鎖的條件有哪些?
答:死鎖是指兩個或以上的進程在執(zhí)行過程中,因爭奪資源而造成一種相互等待的現(xiàn)象,若無外力作用,它們將無法推進下去,如果系統(tǒng)資源充足,進程的資源請求都能得到滿足,死鎖出現(xiàn)的可能性就很低,否則會因爭奪有限的資源而陷入死鎖。
產生死鎖的四個必要條件:
(1) 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
(3) 不剝奪條件:進程已獲得的資源,在未使用完之前,不能強行剝奪。
(4) 循環(huán)等待條件:若干進程之間形成一種頭尾相接的循環(huán)等待資源關系。
只要上述條件之一不滿足,就不會發(fā)生死鎖。避免死鎖的算法 -- 銀行家算法
?
5.為什么wait、notify和notifyAll這些方法不在Thread類里面?
答:Java提供的鎖是對象級別的,而不是線程級別的,每個對象都有鎖,通過線程獲得。如果線程需要等待某些鎖,那么調用對象的wait()就有意義了。如果wait()方法定義在Thread類中,線程等待哪個對象的鎖就不確定了。由于wait()、notify()和notifyAll()都是鎖級別的操作,所以把它們定義在Object類中就是因為鎖屬于對象。
?
6.Java多線程中調用wait() 和 sleep()方法有什么不同?
答:wait()方法用于線程間的通信,如果等待條件為真且其他線程被喚醒時它會釋放鎖,而sleep()方法僅僅釋放CPU資源或者讓當前線程停止一段時間,但不會釋放鎖。
?
7.有三個線程T1,T2,T3,怎么確保它們按順序執(zhí)行?
答:在多線程中有多種方法讓線程按特定順序執(zhí)行,你可以用線程類的join()方法在一個線程中啟動另一個線程,另外一個線程完成該線程繼續(xù)執(zhí)行。為了確保三個線程的順序你應該先啟動最后一個(T3調用T2,T2調用T1),這樣T1就會先完成而T3最后完成。
?
8.線程有幾種狀態(tài),他們是怎么轉化的?
答:線程的生命周期大體分為5種狀態(tài):新建、就緒、執(zhí)行、阻塞、死亡。
新建:?通過new關鍵字創(chuàng)建Thread類的對象;
就緒: 對象調用start()方法;
運行:處于就緒狀態(tài)的線程一旦得到CPU,就進入運行狀態(tài)并自動調用自己的run()方法;
阻塞:處于運行狀態(tài)的線程,執(zhí)行sleep()方法,或等待I/O設備資源,讓出CPU并暫時中止自己運行,進入阻塞狀態(tài)
阻塞 --> 就緒:睡眠時間已到,或等待的I/O設備空閑下來,線程便進入就緒狀態(tài),重新到就緒隊列中等待CPU。當再次獲得CPU時,便從原來中止位置開始繼續(xù)運行。
死亡:(正常情況下)線程任務完成,或者主線程的main()方法完成時,線程就被認為死亡。死去的線程不能復生。
?
9.多線程上下文切換是什么?
答:多線程上下文切換就是指CPU控制權由一個已經(jīng)正在運行的線程切換到另外一個就緒并等待獲取CPU執(zhí)行權的線程的過程。
?
----------有時間再繼續(xù)寫----------
總結
以上是生活随笔為你收集整理的面试 -- 多线程( 一) -- 基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面试 -- Java基础(一)
- 下一篇: csgo卡程序关不掉_微信推QQ小程序,