標籤:定時 分享 函數 狀態 限制 告訴 inter alt notify
問題1.進程與線程的關係
進程:進程指正在啟動並執行程式。確切的來說,當一個程式進入記憶體運行,即變成一個進程,進程是處於運行過程中的程式,並且具有一定獨立功能。
線程:線程是進程中的一個執行單元,負責當前進程中程式的執行,一個進程中至少有一個線程。一個進程中是可以有多個線程的,這個應用程式也可以稱之為多線程程式。
簡而言之:一個程式運行後至少有一個進程,一個進程中可以包含多個線程
問題2.多線程兩種實現方式
①建立線程方式一繼承Thread類
建立線程的步驟:
1 定義一個類繼承Thread。
2 重寫run方法。
3 建立子類對象,就是建立線程對象。
4 調用start方法,開啟線程並讓線程執行,同時還會告訴jvm去調用run方法。
②建立線程方式—實現Runnable介面
1、定義類實現Runnable介面。
2、覆蓋介面中的run方法。。
3、建立Thread類的對象
4、將Runnable介面的子類對象作為參數傳遞給Thread類的建構函式。
5、調用Thread類的start方法開啟線程。
思考:線程對象調用 run方法和調用start方法區別?
線程對象調用run方法不開啟線程。僅是對象調用方法。線程對象調用start開啟線程,並讓jvm調用run方法在開啟的線程中執行
思考:我們為什麼要繼承Thread類,並調用其的start方法才能開啟線程呢?
繼承Thread類:因為Thread類用來描述線程,具備線程應該有功能。那為什麼不直接建立Thread類的對象呢?如下代碼:
Thread t1 = new Thread();t1.start();//這樣做沒有錯,但是該start調用的是Thread類中的run方法,而這個run方法沒有做什麼事情,更重要的是這個run方法中並沒有定義我們需要讓線程執行的代碼。
問題3.多線程兩種實現方式的區別
---- 為什麼需要定一個類去實現Runnable介面呢?繼承Thread類和實現Runnable介面有啥區別呢?
實現Runnable介面,避免了繼承Thread類的單繼承局限性(你不能讓我的類只繼承而不繼承別的類吧)。覆蓋Runnable介面中的run方法,將線程任務代碼定義到run方法中。
建立Thread類的對象,只有建立Thread類的對象才可以建立線程。線程任務已被封裝到Runnable介面的run方法中,而這個run方法所屬於Runnable介面的子類對象,所以將這個子類對象作為參數傳遞給Thread的建構函式,這樣,線程對象建立時就可以明確要啟動並執行線程的任務。
問題4.線程池的原理
線程池,其實就是一個容納多個線程的容器,其中的線程可以反覆使用,省去了頻繁建立線程對象(既new Thread();)的操作,無需反覆建立線程而消耗過多資源。
------詳細的解釋一下為什麼要使用線程池?
在java中,如果每個請求到達就建立一個新線程,開銷是相當大的。在實際使用中,建立和銷毀線程花費的時間和消耗的系統資源都相當大,甚至可能要比在處理實際的使用者請求的時間和資源要多的多。除了建立和銷毀線程的開銷之外,活動的線程也需要消耗系統資源。如果在一個jvm裡建立太多的線程,可能會使系統由於過度消耗記憶體或“切換過度”而導致系統資源不足。為了防止資源不足,需要採取一些辦法來限制任何給定時刻處理的請求數目,儘可能減少建立和銷毀線程的次數,特別是一些資源耗費比較大的線程的建立和銷毀,盡量利用已有對象來進行服務。
線程池主要用來解決線程生命週期開銷問題和資源不足問題。通過對多個任務重複使用線程,線程建立的開銷就被分攤到了多個任務上了,而且由於在請求到達時線程已經存在,所以消除了線程建立所帶來的延遲。這樣,就可以立即為請求服務,使用應用程式響應更快。另外,通過適當的調整線程中的線程數目可以防止出現資源不足的情況。
問題5.線程的生命週期
① 建立狀態(New Thread) :在Java語言中使用new 操作符建立一個線程後,該線程僅僅是一個Null 物件,它具備類線程的一些特徵,但此時系統沒有為其分配資源,這時的線程處於建立狀態。
線程處於建立狀態時,可通過Thread類的方法來設定各種屬性,如線程的優先順序(setPriority)、線程名(setName)和線程的類型(setDaemon)等。
②就緒狀態(Runnable):使用start()方法啟動一個線程後,系統為該線程分配了除CPU外的所需資源,使該線程處於就緒狀態。
③ 運行狀態(Running):Java運行系統通過調度選中一個處於就緒狀態的線程,使其佔有CPU並轉為運行狀態。此時,系統真正執行線程的run()方法。
④ 阻塞和喚醒線程
阻塞狀態(Blocked):一個正在啟動並執行線程因某些原因不能繼續運行時,就進入阻塞 狀態。這些原因包括:
(a) 當執行了某個線程對象的sleep()等阻塞類型的方法時,該線程對象會被置入一個阻塞集內,等待逾時而自動蘇醒。
(b) 當多個線程試圖進入某個同步地區時,沒能進入該同步地區的線程會被置入鎖定集,直到獲得該同步地區的鎖,進入就緒狀態。
(c) 當線程執行了某個對象的wait()方法時,線程會被置入該對象的等待集中,知道執行了該對象的notify()方法wait()/notify()方法的執行要求線程首先獲得該對象的鎖。
⑤ 死亡狀態(Dead):線程在run()方法執行結束後進入死亡狀態。此外,如果線程執行了interrupt()或stop()方法,那麼它也會以異常退出的方式進入死亡狀態。
java線程的小問題與回答