什麼是線程?
答:是作業系統能夠進行運算排程的最小機關。它被包含在程序之中,是程序中的實際運作機關---------------------->個人認為是在一個程式中(程序)的一個獨立,而且可以多個并行執行的一條執行路徑。
什麼是程序?
答:程序是由多個線程執行個體組成的一組線程的集合,它可以看出是一個程式運作的執行個體
線程和程序的差別?
答:到了這裡應該很明确了,線程是一組線程的一個集合,線程是一個程序中的一個獨立的可以并行執行的一個執行路徑。
回到我們的主題:多線程
顧名思義,多線程就是很多個線程,那麼線程的特點是什麼,可以并行執行,而且是一條獨立的執行路徑。
那麼我們可以看出多線程的優點:提高程式的執行效率,如果還不了解,那麼我們就舉個栗子:

通過上面的圖,我們可以很清晰的看到,貨物a之後一個卡車在拉貨,完成任務需要五個小時,但是貨物b是三個卡車在拉貨,而且每個卡車都有屬于自己的道路,也就不會存在堵車的情況,那麼效率會相對于貨物a大大提高。那麼多線程的優點久跟這個原理一樣。可以提高程式執行效率。
那麼多線程真的是同時在進行執行嗎?其實多線程不是在同時執行的,多線程會進行對CPU的搶渡,多個線程在就緒狀态之後,CPU會進行随機配置設定資源,那個線程拿到資源就可以進行執行,當然這是非常非常短暫的一個時間,我們幾乎是可能感覺得到得,是以才說是在并行進行執行,而且是獨立的,也就是說線程與線程之間是互不影響的,
總結:就是線程是CPU随機進行配置設定資源,拿到資源的才可以進行運作,但是時間是非常短的,是以對于我們可以說是同時進行執行的,其次,就是線程是獨立的,互不影響的。
凡事都是物極必反的,多線程同樣如此,就拿上圖來說把,雖然我們這裡使用了三個卡車進行執行,效率變快了,但是也需要老闆有哪個實力啊,如果你沒有那麼多錢,還叫那麼多卡車,最後會導緻什麼結果,多線程也是如此,就算線程能提高程式執行效率,但是也不能盲目的使用,要根據自己的硬體也就是CPU進行合理配置設定才行。
多線程使用場景:執行比較耗時,但是又不希望影響到主線程的東西,比如下載下傳,資料庫連接配接池等
好了下面我們就開始在java中使用多線程
首先我們得了解一下如何建立一個多線程,多線程的建立方式有很多,這裡列舉三個:
1:繼承Thread類
class CreateThread extends Thread {
// run方法中編寫 多線程需要執行的代碼
publicvoid run() {
for (inti = 0; i< 10; i++) {
System.out.println("i:" + i);
}
}
}
publicclass ThreadDemo {
publicstaticvoid main(String[] args) {
System.out.println("-----多線程建立開始-----");
// 1.建立一個線程
CreateThread createThread = new CreateThread();
// 2.開始執行線程 注意 開啟線程不是調用run方法,而是start方法
System.out.println("-----多線程建立啟動-----");
createThread.start();
System.out.println("-----多線程建立結束-----");
}
}
那麼執行結果為:
為什麼出現這種情況:那是因為線程是獨立的一條執行路徑,上面的代碼中存在兩個線程,其中main方法是主線程,我們自定義的類是子線程,由于主線程之中的東西非常少,是以在我們子線程還沒有執行完畢我們的主線程就執行完畢了,是以才會有這樣的結果。
2:實作Runnable接口
class CreateRunnable implements Runnable {
@Override
publicvoid run() {
for (inti = 0; i< 10; i++) {
System.out.println("i:" + i);
}
}
}
publicclass ThreadDemo2 {
publicstaticvoid main(String[] args) {
System.out.println("-----多線程建立開始-----");
// 1.建立一個線程
CreateRunnable createThread = new CreateRunnable();
// 2.開始執行線程 注意 開啟線程不是調用run方法,而是start方法
System.out.println("-----多線程建立啟動-----");
Thread thread = new Thread(createThread);
thread.start();
System.out.println("-----多線程建立結束-----");
}
}
這上面的運作結果跟繼承thread類的差不多,同理
3:匿名内部類方式
public class CreateThread {
public static void main(String[] args) {
System.out.println("主線程開始執行");
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("子線程開始執行");
for (int i = 0 ; i < 10 ; i++){
System.out.println("i:"+i);
}
System.out.println("子線程執行結束");
}
});
thread.start();
System.out.println("主線程執行完畢");
}
}
執行結果,同理
----多線程推薦事項繼承Runnable接口,我們還是要面向接口程式設計哈
另外啟動多線程是thread.start(),很多初學的小夥伴會認為是thread.run(),run()方法隻是人家多線程執行的一個入口,我們需要使用多線程執行的東西就是放在run方法裡面的,但是啟動多線程還是使用thread.start()
我們建立了多線程,并且可以輸出列印一段話了,那麼多線程的執行流程是如何的,那就要說到我們線程的五個狀态,建立,就緒,運作,阻塞,銷毀
建立:就是我麼建立了一個Thread的執行個體,但是沒有做任何操作
就緒:即是我們調用thread.start()方法,因為前面也說了,線程的運作是拿到CPU的資源之後才會執行,沒拿到就會進行等待,是以說調用thread.start()是就緒狀态,因為這之間的時間是非常短暫的,是以往往調用了thread.start()就會執行,讓人誤以為thread.start()就是啟動線程
運作:這個時候線程拿到了CPU的資源,進行執行run方法了
阻塞:這種情況就是線程在一些情況下停止了繼續往後面執行,比如等待别的真正使用的鎖,使用sleep方法,等很多
銷毀:當線程發生未捕獲的錯誤,或者正常執行完畢之後,線程就會進行銷毀
常用線程api方法 | |
start() | 啟動線程 |
currentThread() | 擷取目前線程對象 |
getID() | 擷取目前線程ID Thread-編号 該編号從0開始 |
getName() | 擷取目前線程名稱 |
sleep(long mill) | 休眠線程 |
Stop() | 停止線程, |
isAlive() | 如果線程是正在允許或者被阻塞傳回true,如果是沒有就緒或者死亡的線程傳回false |
Join() | 可以讓一個線程優先執行 |
setPriority() | 設定線程的優先級,也就是擷取CPU的可能性會更大,但是可能看不出效果,可以傳遞0~10 |
常用線程構造函數 | |
Thread() | 配置設定一個新的 Thread 對象 |
Thread(String name) | 配置設定一個新的 Thread對象,具有指定的 name正如其名。 |
Thread(Runable r) | 配置設定一個新的 Thread對象 |
Thread(Runable r, String name) | 配置設定一個新的 Thread對象 |
另外可以使用idea工具點選進入Thread類,可以看到更多。