java併發編程之多線程基礎

什麼是線程?

 答:是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位---------------------->個人認爲是在一個程序中(進程)的一個獨立,而且可以多個並行執行的一條執行路徑

什麼是進程?

答:進程是由多個線程實例組成的一組線程的集合,它可以看出是一個程序運行的實例

線程和進程的區別?

答:到了這裏應該很明確了,線程是一組線程的一個集合,線程是一個進程中的一個獨立的可以並行執行的一個執行路徑。

回到我們的主題:多線程

顧名思義,多線程就是很多個線程,那麼線程的特點是什麼,可以並行執行,而且是一條獨立的執行路徑。

那麼我們可以看出多線程的優點:提高程序的執行效率,如果還不理解,那麼我們就舉個栗子:

通過上面的圖,我們可以很清晰的看到,貨物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類,可以看到更多。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章