摘要:一個進程可以擁有多個線程,一個線程必須有一個父進程。線程是獨立運行的,它并不知道進程中是否還有其他的線程存在。線程的調度和管理由進程本身負責完成。因此多線程實現多任務并發比多線程的效率高。
??一個任務通常就是一個程序,每個運行中的程序就是一個進程。當一個程序運行時,內部可能包含了多個順序執行流,每個順序執行流就是一個線程。
進程定義:
??當一個程序進入內存運行時,即變成一個進程。進程是處于運行過程中的程序,并且具有一定的獨立功能,進程是系統進行資源分配和調度的一個獨立單位。
進程的特點:獨立性:是系統獨立存在的實體,擁有自己獨立的資源,有自己私有的地址空間。在沒有經過進程本身允許的情況下,一個用戶的進程不可以直接訪問其他進程的地址空間。
動態性:進程與程序的區別在于:程序只是一個靜態的指令集合,而進程是一個正在系統中活動的指令集和,進程中加入了時間的概念。進程具有自己的生命周期和不同的狀態,這些都是程序不具備的。
并發性:多個進程可以在單個處理器上并發執行,多個進程之間不會相互影響。
并行性和并發性??并行:指在同一時刻,有多條指令在多個處理上同時執行。(多核同時工作)
??并發:指在同一時刻只能有一條指令執行,但多個進程指令被快速輪換執行,使得在宏觀上具有多個進程同時執行的效果。(單核在工作,單核不停輪詢)
線程??多線程擴展了多進程的概念,使得同一個進程可以同時并發處理多個任務。
??線程(Thread)也被成為輕量級的進程,線程是進程執行的單元,線程在程序中是獨立的、并發的執行流
??當進程被初始化后,主線程就被創建了。絕大數應用程序只需要有一個主線程,但也可以在進程內創建多條的線程,每個線程也是相互獨立的。
??一個進程可以擁有多個線程,一個線程必須有一個父進程。
??線程可以擁有自己的堆棧、自己的程序計數器和自己的局部變量,但不擁有系統資源,它與父進程的其他線程共享該進程所擁有的全部資源,因此編程更加方便。
??線程是獨立運行的,它并不知道進程中是否還有其他的線程存在。線程的執行是搶占式的,即:當前運行的線程在任何時候都有可能被掛起,以便另外一個線程可以運行。
??一個線程可以創建和撤銷另一個線程,同一個進程中多個線程之間可以并發執行。
??線程的調度和管理由進程本身負責完成。
??歸納而言:操作系統可以同時執行多個任務,每個任務就是進程;進程可以同時執行多個任務,每個任務就是線程
多線程的優點:
進程之間不能共享內存,但線程之間共享內存非常容易
系統創建進程要為該進程重新分配系統資源,但創建線程的代價則小得多。因此多線程實現多任務并發比多線程的效率高。
Java語言內置了多線程功能支撐,簡化了多線程的編程。
線程的創建和啟動一、繼承Thread類創建線程類
步驟:
① 定義Thread類的子類,并重寫該類的run()方法,該run()方法的方法體就代表了線程需要完成的任務,稱為線程執行體
② 創建Thread子類的實例,即創建了線程對象
③ 調用線程對象的start()方法來啟動該線程
示例:
// 通過繼承Thread類來創建線程類 public class FirstThread extends Thread { private int i ; // 重寫run方法,run方法的方法體就是線程執行體 public void run() { for ( ; i < 100 ; i++ ) { // 當線程類繼承Thread類時,直接使用this即可獲取當前線程 // Thread對象的getName()返回當前該線程的名字 // 因此可以直接調用getName()方法返回當前線程的名 System.out.println(getName() + " " + i); } } public static void main(String[] args) { for (int i = 0; i < 100; i++) { // 調用Thread的currentThread方法獲取當前線程 System.out.println(Thread.currentThread().getName() + " " + i); if (i == 20) { // 創建、并啟動第一條線程 new FirstThread().start(); // 創建、并啟動第二條線程 new FirstThread().start(); } } } }
① 當Java程序開始運行后,程序至少會創建一個主線程,main()方法的方法體代表主線程的線程執行體
② 當線程類繼承Tread類時,直接使用this即可以獲取當前線程
③ 繼承Thread類創建線程類,多個線程之間無法共享線程類的實例變量
二、實現Runnable接口創建線程類① 定義Runnable接口的實現類,并重寫該接口的run()方法
② 創建Runnable實現類的實例,并以此實例作為Thread的target來創建Tread對象,該Tread對象才是真正的線程對象
// 通過實現Runnable接口來創建線程類 public class SecondThread implements Runnable { private int i ; // run方法同樣是線程執行體 public void run() { for ( ; i < 100 ; i++ ) { // 當線程類實現Runnable接口時, // 如果想獲取當前線程,只能用Thread.currentThread()方法。 System.out.println(Thread.currentThread().getName() + " " + i); } } public static void main(String[] args) { for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + " " + i); if (i == 20) { SecondThread st = new SecondThread(); // ① // 通過new Thread(target , name)方法創建新線程 new Thread(st , "新線程1").start(); new Thread(st , "新線程2").start(); } } } }
① 實現Runnable接口創建線程類,必須通過Thread.currentThread()方法來獲得當前線程對象
② 實現Runnable接口創建線程類,多個線程可以共享線程類的實例變量
三、使用Callable和Future創建線程Callable接口提供了一個call()方法,call()方法比run()方法更強大:
① call()方法可以由返回值
② call()方法可以聲明拋出異常
① 創建Callable接口的實現類,并實現call()方法,該call()方法作為線程執行體,且該call()方法有返回值
② 使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了該Callable對象的call()方法的返回值
③ 調用FutureTask對象的get()方法獲得子線程執行結束的返回值
創建線程三種方式的對比:優點:
①實現的是接口,還可以繼承其他類
② 多個線程可以共享同一個target對象,適合多個相同的線程來處理同一份資源的情況
缺點:
① 編程稍微復雜
② 獲取當前線程必須用Thread.currentThread()方法來獲得
優點:
①編程簡單
② 獲取當前線程,可以直接使用this來獲得
缺點:
① 已經繼承了Thread類,不能繼承其他類
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69113.html
摘要:本文主要內容為簡單總結中線程池的相關信息。方法簇方法簇用于創建固定線程數的線程池。三種常見線程池的對比上文總結了工具類創建常見線程池的方法,現對三種線程池區別進行比較。 概述 線程可認為是操作系統可調度的最小的程序執行序列,一般作為進程的組成部分,同一進程中多個線程可共享該進程的資源(如內存等)。在單核處理器架構下,操作系統一般使用分時的方式實現多線程;在多核處理器架構下,多個線程能夠...
摘要:本篇博客主要針對虛擬機的晚期編譯優化,內存模型與線程,線程安全與鎖優化進行總結,其余部分總結請點擊虛擬總結上篇,虛擬機總結中篇。 本篇博客主要針對Java虛擬機的晚期編譯優化,Java內存模型與線程,線程安全與鎖優化進行總結,其余部分總結請點擊Java虛擬總結上篇 ,Java虛擬機總結中篇。 一.晚期運行期優化 即時編譯器JIT 即時編譯器JIT的作用就是熱點代碼轉換為平臺相關的機器碼...
閱讀 2738·2021-10-11 10:57
閱讀 1569·2021-09-26 09:55
閱讀 1310·2021-09-06 15:11
閱讀 3447·2021-08-26 14:16
閱讀 662·2019-08-30 15:54
閱讀 535·2019-08-30 12:43
閱讀 3290·2019-08-29 16:18
閱讀 2565·2019-08-23 16:14