1.進程、線程、并發、并行是什么?
1)進程:操作系統中可以運行多個任務(程序),這些運行的任務(程序)被稱為進程。程序的運行產生進程(內存空間、程序執行的堆棧),可以這樣說,進程是作為操作系統分配資源的基本單位。
2)線程:程序里同時可能運行多個任務(在一個CPU時間片內,順序執行流),那么每個任務(順序執行流)就叫做一個線程,即在線程內部。
3)并發:線程是并發運行的。操作系統將時間化分為若干個片段(時間片),盡可能的均勻分配給每一個任務,被分配時間片后,任務就有機會被cpu所執行。微觀上看,每個任務都是走走停停的。但隨著cpu高效的運行,宏觀上看所有任務都在運行。這種都運行的現象稱之為并發,但不是絕對意義上的“同時發生”。
?4)并行:一個時間段,多個任務同時進行,而且多個CPU運行各自的進程。
?2.多線程的實現
1)繼承Thread
?通過查閱JDK API文檔,Thread 類位于java.lang中,表示進程中的執行線程。實現多線程有兩種方式。第一是繼承Thread:
1 package cn.a1.a; 2 3 public class MyThread extends Thread { 4 5 @Override 6 public void run() { 7 System.out.println("這是多線程MyThread"); 8 for (int i = 0; i < 5; i++) { 9 System.out.println("MyThread:" + i); 10 } 11 12 } 13 }
1 package cn.a1.a; 2 3 public class Test1 { 4 public static void main(String[] args) { 5 // 創建一個多線程,此時已有兩個線程 主線程(main) 和 創建的線程 mThread1; 6 MyThread mThread1 = new MyThread(); 7 mThread1.start(); 8 9 // 查看主線程main是否運行 10 for (int i = 0; i < 5; i++) { 11 System.out.println("main Thread:" + i); 12 } 13 14 } 15 16 }
main線程和t1線程搶占CPU 執行,輸出也是main線程和t1線程根據內部搶占CPU 執行輸出,不規則,多線程在提高CPU利用率的同時,增加程序的復雜度。
main Thread:0 這是多線程MyThread main Thread:1 MyThread:0 main Thread:2 MyThread:1 main Thread:3 MyThread:2 MyThread:3 main Thread:4 MyThread:4
?
2)實現Runnable接口
用于定義線程要執行的任務邏輯。我們定一個類實現Runnable接口,這時我們必須重寫run方法,在其中定義我們要執行的邏輯。之后將Runnable交給線程去執行。從而實現了線程與其執行的任務分離開。將任務分別交給不同的線程并發處理,可以使用線程的重載構造方法:Thread(Runnable runnable)。解藕:線程與線程體解藕,即打斷依賴關系。 如果你學到Spring了就知道,Spring的ioc就是干這個的。
?演示:
1 package cn.a1.a1; 2 3 public class MyRun implements Runnable { 4 5 @Override 6 public void run() { 7 System.out.println("這是MyRun"); 8 9 for (int i = 0; i < 3; i++) { 10 System.out.println("MyRun:" + i); 11 } 12 } 13 }
?
1 public class Test1 { 2 public static void main(String[] args) { 3 MyRun tRun1 = new MyRun(); 4 Thread t1 = new Thread(tRun1); 5 t1.start(); 6 //這里main開始運行也有產生一個進程,該進程有個主(main)線程 7 for (int i = 0; i < 3; i++) { 8 System.out.println("main"+i); 9 } 10 11 } 12 13 }
輸出不規則的
main0 這是MyRun MyRun:0 main1 main2 MyRun:1 MyRun:2
繼承Thread和實現Runnable接口實現多線程的優缺點
[1] 繼承Thread的線程類不能再繼承其他類,實現Runnable接口的類還可以繼承其他類。
[2] 實現Runnable接口的線程類,可以讓多個線程共享線程實現類的資源。
總結:
多線程提高了cpu利用率,但程序的復雜度也隨之增加。一旦線程開始執行,很難通過其他方式控制線程的軌跡。
多個線程搶占CPU導致線程的運行軌跡不確定。