Java多線程基礎知識點

一、線程與進程區別

       每個正在系統上運行的程序都是一個進程。每個進程包含一到多個線程。線程是一組指令的集合,或者是程序的特殊段,它可以在程序裏獨立執行。也可以把它理解爲代碼運行的上下文。所以線程基本上是輕量級的進程,它負責在單個程序裏執行多任務。通常由操作系統負責多個線程的調度和執行。

使用線程可以把佔據時間長的程序中的任務放到後臺去處理,程序的運行速度可能加快,在一些等待的任務實現上如用戶輸入、文件讀寫和網絡收發數據等,線程就比較有用了。在這種情況下可以釋放一些珍貴的資源如內存佔用等等。

如果有大量的線程,會影響性能,因爲操作系統需要在它們之間切換,更多的線程需要更多的內存空間,線程的中止需要考慮其對程序運行的影響。通常塊模型數據是在多個線程間共享的,需要防止線程死鎖情況的發生。

區別總結:        進程是所有線程的集合,每一個線程是進程中的一條執行路徑。

根本區別:進程是資源分配最小單位,線程是程序執行的最小單位。

地址空間:進程有自己獨立的地址空間,每啓動一個進程,系統都會爲其分配地址空間,建立數據表來維護代碼段、堆棧段和數據段;線程沒有獨立的地址空間,同一進程的線程共享本進程的地址空間。

資源擁有:進程之間的資源是獨立的;同一進程內的線程共享本進程的資源。

線程是處理機調度的基本單位,但是進程不是。由於程序執行的過程其實是執行具體的線程,那麼處理機處理的也是程序相應的線程,所以處理機調度的基本單位是線程。

         

 

二、爲什麼要使用多線程?

 多線程的好處提高程序的效率。

 

三、多線程應用場景?

主要能體現到多線程提高程序效率。

舉例: 迅雷多線程下載、分批發送短信等。

 

四、多線程創建方式

繼承Thread類, 重寫run方法

class CreateThread extends Thread {
	// run方法中編寫 多線程需要執行的任務
	public void run() {
		for (int i = 0; i< 10; i++) {
			System.out.println("i:" + i);
		}
	}
}
public class ThreadDemo {

	public static void main(String[] args) {

		// 1.創建一個線程
		CreateThread createThread = new CreateThread();
		// 2.開始執行線程 注意 開啓線程不是調用run方法,而是start方法
		createThread.start();

	}

}

實現Runnable接口,重寫run方法

class CreateRunnable implements Runnable {

	@Override
	public void run() {
		for (int i = 0; i< 10; i++) {
			System.out.println("i:" + i);
		}
	}

}

public class ThreadDemo2 {
	public static void main(String[] args) {

		// 1.創建一個線程
		CreateRunnable createThread = new CreateRunnable();
		// 2.開始執行線程 注意 開啓線程不是調用run方法,而是start方法
		Thread thread = new Thread(createThread);
		thread.start();

	}
}

③使用匿名內部類方式

public class ThreadDemo2 {
	public static void main(String[] args) {
        //看需要選下面兩種吧
		// Thread thread = new Thread(new Runnable() {
		// 	public void run() {
		// 		for (int i = 0; i< 10; i++) {
		// 			System.out.println("i:" + i);
		// 		}
		// 	}
		// });
		//thread.start();

		new Thread(new Runnable() {
			public void run() {
				for (int i = 0; i< 10; i++) {
					System.out.println("i:" + i);
				}
			}
		}).start();
	}
}

問題:

①使用繼承Thread類還是使用實現Runnable接口好

使用實現實現Runnable接口好,原因實現了接口還可以繼續繼承,繼承了類不能再繼承。

②啓動線程是使用調用start方法還是run方法?

開始執行線程 注意 開啓線程不是調用run方法,而是start方法

調用run只是使用實例調用重寫的run方法,並沒有新線程出現。

 

五、基本的幾個函數

其中currentThread注意一下,這個比較重要,比如你實現了Runnable接口,在重寫run方法中可以使用Thread.currentThread()

就可以獲得當前cpu正在執行的是哪個線程,你可以獲取線程名字啊,線程id啊。

 

六、多線程運行狀態

http://www.blogjava.net/images/blogjava_net/santicom/360%E6%88%AA%E5%9B%BE20110901211600850.jpg

 線程從創建、運行到結束總是處於下面五個狀態之一:新建狀態、就緒狀態、運行狀態、阻塞狀態及死亡狀態。

① 新建狀態

   當用new操作符創建一個線程時, 例如new Thread(r),線程還沒有開始運行,此時線程處在新建狀態。 當一個線程處於新生狀態時,程序還沒有開始運行線程中的代碼

② 就緒狀態

一個新創建的線程並不自動開始運行,要執行線程,必須調用線程的start()方法。當線程對象調用start()方法即啓動了線程,start()方法創建線程運行的系統資源,並調度線程運行run()方法。當start()方法返回後,線程就處於就緒狀態。

     處於就緒狀態的線程並不一定立即運行run()方法,線程還必須同其他線程競爭CPU時間,只有獲得CPU時間纔可以運行線程。因爲在單CPU的計算機系統中,不可能同時運行多個線程,一個時刻僅有一個線程處於運行狀態。因此此時可能有多個線程處於就緒狀態。對多個處於就緒狀態的線程是由Java運行時系統的線程調度程序(thread scheduler)來調度的。

③ 運行狀態

當線程獲得CPU時間後,它才進入運行狀態,真正開始執行run()方法.

④ 阻塞狀態

    線程運行過程中,可能由於各種原因進入阻塞狀態:
        1>線程通過調用sleep方法進入睡眠狀態;
        2>線程調用一個在I/O上被阻塞的操作,即該操作在輸入輸出操作完成之前不會返回到它的調用者;
        3>線程試圖得到一個鎖,而該鎖正被其他線程持有;
        4>線程在等待某個觸發條件;
 

⑤ 死亡狀態

有兩個原因會導致線程死亡:
  1) run方法正常退出而自然死亡,
   2) 一個未捕獲的異常終止了run方法而使線程猝死。
  爲了確定線程在當前是否存活着(就是要麼是可運行的,要麼是被阻塞了),需要使用isAlive方法。如果是可運行或被阻塞,這個方法返回true; 如果線程仍舊是new狀態且不是可運行的, 或者線程死亡了,則返回false.

 

後面一篇是線程同步哦,希望大大萌看看。

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