首先:線程與進程的區別是什麼呢?
進程:正在運行的一個程序稱之為一個進程,進程負責了內存空間的劃分,從宏觀的角度:windows是在同時執行多個程序
從微觀的角度看,CPU是在快速的切換要執行的程序。實質上,一個時間片上只有一個程序在執行。
線程:線程負責了代碼的執行,就是進程中的執行路徑。
多線程:在一個進程中有多個線程同時在執行不同的任務
疑問1:線程負責了代碼的執行,我們之前沒使用線程為什麼代碼可以執行?
答:JVM在運行的時候會自動創建一個main線程執行main方法中的代碼。
疑問2:一個JAVA程序至少需要幾個線程?
答:至少需要2個線程,一個是主線程負責main方法的代碼,另外一個是垃圾回收器的線程負責回收垃圾。
多線程的好處:1.解決了一個程序能夠執行多個任務的問題
2.多線程並沒有提高效率 而是提高了資源的利通率。
多線程的弊端:
1.增加了CPU的負擔
2.容易引發線程安全問題
3.出現了死鎖的現象
那麼我們如何創建多線程呢?
方式1:繼承Thread類,並重寫run()方法,並將自定義線程的任務代碼寫在run方法裡。創建繼承自Thread類的對象,然後調用start()方法開啟線程。
方式2:實現Runnable接口,並實現run()方法。將自定義線程的任務代碼寫在run()方法裡。創建實現Runnable接口的類的對象,然後將對象作為實參傳遞給Thread方法創建線程對象,然後調用start()方法開啟線程。
疑問:為什麼要重寫run方法,重寫run方法的目的?
答:每個線程都有自己的任務代碼,jvm創建的主線程任務代碼就是main方法中的所有代碼,自定義線程的任務代碼就寫在run方法中,自定義線程負責了run方法中的代碼
注意: run方法不能直接調用,直接調用run方法就相當於調用了一個普通的方法而已,並沒有開啟新的線程
問題1:請問Runnable實現類的對象是線程對象嗎?
Runnable實現類的對象並不是線程對象,只不過實現了Runnable接口的對象而已
只有Thread或者Thread子類才能是線程對象 線程都有start方法開啟線程
問題2:為什麼要把Runnable實現類的對象作為實參傳遞給Thread對象?作用是什麼?
Thread類使用target變量記錄了t1對象
源碼:public void run() {
if (target != null) {
target.run(); //將Runnable實現類的run方法作為線程對象的run方法
}
}
推薦使用第二種方式創建自定義線程:因為java是單繼承多實現的
線程常用的方法:
Thread(String name) 初始化線程的名字
getName() 返回線程的名字
setName(String name) 設置線程對象名
sleep() 線程睡眠指定的毫秒數。是一個靜態的方法,哪個線程執行了sleep方法那麼就是哪個線程睡眠
為什麼sleep不能拋出異常,只能捕獲?
答:子類在重寫Thread的run()方法,方法重寫時子類拋出的異常類型要小於或者等於父類的異常類型。
Thread中run()沒有拋出異常,所以子類也不能拋出異常。所以不能直接把異常拋出所以采用捕獲的方法
currentThread() 返回當前CPU正在執行的線程的對象 哪個線程執行的 就返回哪個線程的對象
getPriority() 返回當前線程對象的優先級 默認線程的優先級是5 優先級數字越大的 執行的概率越高
setPriority(int newPriority) 設置線程的優先級 雖然設置了線程的優先級,但是具體的實現取決於底層的操作系統的實現(最大的優先級是10 ,最小的1 , 默認是5)。