Java4Android自學記錄(24-1):java基礎之創建線程

道阻且長,行則將至。埋頭苦幹,不鳴則已,一鳴驚人!加油,騷年!

目錄及資源索引

  Java4Android自學過程目錄及資源索引

1 多進程與多線程

  簡單地說,多進程:在操作系統中能(同時)運行多個任務(程序);多線程:在同一應用程序中有多個順序流(同時)執行。

  每啓動一個應用,就是啓動一個進程。對於 Android ,原則上來講,一個軟件只有一個進程。

2 線程的執行過程

  參考老師課件,有如下示例,類似一個抽水機,兩條水管同時在抽水;

2.1 線程執行流程圖

  線程的整個執行過程,簡要總結一下就是:創建一個新線程 -> 啓動線程 -> 線程運行(受控調度) -> 運行完畢 -> 線程釋放/回收;

  參考老師圖片,總結如下:

  針對上圖,再次理解線程執行過程:先創建線程,然後開始運行,然後進入就緒狀態,接着進入運行狀態,然後等待 CPU 調度,進入阻塞,然後解除阻塞,接着運行,等等,直到運行完畢,銷燬線程。

3 創建線程的方法

3.1 方法一:繼承類 Thread

  定義一個線程類,繼承類 Thread ,並且重寫其中的方法 run() ,方法 run() 稱爲線程體;

  注意:由於 java 只支持單繼承,用這種方法定義的類不能再繼承其他類。

  具體實現方法呢,看下邊代碼

class FirstThread extends Thread
{
	public void run()
	{
		for(int i = 0; i < 100; i++)
		{
			System.out.println("FirstThread-->" + i);
		}
	}
}

  再新建一個主函數類,具體代碼如下:

class Test
{
	public static void main(String args[])
	{
		// 生成線程類的對象
		FirstThread ft = new FirstThread();
		
		// 啓動線程
		ft.start();
	}
}

  上述代碼,與我們一開始的思路都保持一致,主函數中的內容也很簡單,new 一個對象,然後啓動線程,就完事兒了。

  那麼上述代碼運行過程是怎麼樣的呢?

  上邊只是截圖下來一部分的內容,由於使用了 for 循環,因此他會一直走完所有步驟。

  那麼問題就來了,猜猜此時幾個線程正在運行?沒錯,答案就是 2 個,因爲 main 函數本身也是一個線程,我們稱之爲主線程。那麼怎麼驗證一下我們的結論呢?在主函數中在新增一些打印就好了,如下:

class Test
{
	public static void main(String args[])
	{
		// 生成線程類的對象
		FirstThread ft = new FirstThread();
		
		// 啓動線程
		ft.start();
		
		for(int i = 0; i < 100; i++)
		{
			System.out.println("main-->" + i);
		}
	}
}

  程序編譯後的運行結果如下,會發現這兩個線程是在交替運行的

  此時問題又來了,我們不是常說線程是可以同時運行的嗎?注意啦,此時所說的 “同步” ,是從宏觀層面來說,比如運行一次 A 或 B 需要 1ms ,如果在 1 個小時內,A B 依次交替運行,也就是 A 在這段時間內運行 30 分鐘,B 也運行30分鐘, 如果把比例尺放大,從遠處看,就可以說 A B 是在同時運行;但是,如果把比例尺縮小,從近處看,確實 A B 不是在同步運行,也就是微觀看到的 A 先運行 1ms ,B 再運行 1ms ,依次交替運行。

  注意:如果不使用 ft.start() ,直接使用 ft.run(),則就是在一個線程內運行程序,不是多線程。

3.2 方法二:實現接口 Runnable

  提供一個實現接口 Runnable 的類作爲線程的目標對象,在初始化一個 Thread 類或者 Thread 子類的線程對象時,把目標對象傳遞給這個線程實例,由該目標對象提供線程體。

  注意此時我們繼承的是一個 接口 ,代碼如下:

class RunnableImpl implements Runnable
{
	public void run()
	{
		for(int i = 0; i < 100; i++)
		{
			System.out.println("Runnable-->" + i);
		}
	}
}

   主函數代碼如下:

class Test
{
	public static void main(String args[])
	{
		// 生成一個 Runnable 接口實現類的對象
		RunnableImpl ri = new RunnableImpl();
		
		// 生成一個Thread對象,並將Runnable接口實現類的對象作爲
		// 參數傳遞給該Thread對象(參數爲Runnable類型的)
		Thread t = new Thread(ri);
		
		// 通知Thread對象,執行start方法
		t.start();
	}
}

  上述代碼,編譯後運行結果如下:

3.3 總結兩種方法

  第一種是繼承 Thread 類;第二種是實現 Runnable 接口;

  在實際使用中,對繼承能不用就不用,因爲 java 只能支持單繼承,因此還是實現接口比較好。

4 總結

  1. 簡單瞭解 java 中創建線程的兩種方法,以及各自的優劣點;
  2. 實際使用基本代碼進行練習,但是還不夠深入;
  3. 後續需要深入瞭解,把基礎打牢;

如果文章內容有誤,麻煩評論/私信多多指教,謝謝!如果覺得文章內容還不錯,留個讚唄,您的點贊就是對我最大的鼓勵,謝謝您嘞!

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