天天看點

java并發程式設計之多線程基礎

什麼是線程?

 答:是作業系統能夠進行運算排程的最小機關。它被包含在程序之中,是程序中的實際運作機關---------------------->個人認為是在一個程式中(程序)的一個獨立,而且可以多個并行執行的一條執行路徑。

什麼是程序?

答:程序是由多個線程執行個體組成的一組線程的集合,它可以看出是一個程式運作的執行個體

線程和程序的差別?

答:到了這裡應該很明确了,線程是一組線程的一個集合,線程是一個程序中的一個獨立的可以并行執行的一個執行路徑。

回到我們的主題:多線程

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

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

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("-----多線程建立結束-----");
	}

}
           

那麼執行結果為:

java并發程式設計之多線程基礎

為什麼出現這種情況:那是因為線程是獨立的一條執行路徑,上面的代碼中存在兩個線程,其中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("主線程執行完畢");
    }
}
           

執行結果,同理

java并發程式設計之多線程基礎

----多線程推薦事項繼承Runnable接口,我們還是要面向接口程式設計哈

另外啟動多線程是thread.start(),很多初學的小夥伴會認為是thread.run(),run()方法隻是人家多線程執行的一個入口,我們需要使用多線程執行的東西就是放在run方法裡面的,但是啟動多線程還是使用thread.start()

我們建立了多線程,并且可以輸出列印一段話了,那麼多線程的執行流程是如何的,那就要說到我們線程的五個狀态,建立,就緒,運作,阻塞,銷毀

建立:就是我麼建立了一個Thread的執行個體,但是沒有做任何操作

就緒:即是我們調用thread.start()方法,因為前面也說了,線程的運作是拿到CPU的資源之後才會執行,沒拿到就會進行等待,是以說調用thread.start()是就緒狀态,因為這之間的時間是非常短暫的,是以往往調用了thread.start()就會執行,讓人誤以為thread.start()就是啟動線程

運作:這個時候線程拿到了CPU的資源,進行執行run方法了

阻塞:這種情況就是線程在一些情況下停止了繼續往後面執行,比如等待别的真正使用的鎖,使用sleep方法,等很多

銷毀:當線程發生未捕獲的錯誤,或者正常執行完畢之後,線程就會進行銷毀

java并發程式設計之多線程基礎
常用線程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類,可以看到更多。

繼續閱讀