多進程與多線程
1. 多進程:
進程是程序的一次動態執行過程,是代碼加載,代碼執行和代碼執行完成的一個完整的過程。多進程是操作系統級別的概念,它區分的是不同的正在被執行程序。由於CPU具備分時機制,每個進程都能循環的獲得自己的CPU時間片,因爲CPU執行速度非常快,使得用戶覺得所有程序像在“同時”運行一樣。
2. 多線程:
線程是程序執行過程中最小的調度單位,是在進程的基礎上進一步劃分,是比進程更小的執行單位。多線程是程序執行基本的概念,它區分的是程序內部不同的執行單元。這些線程可以同時存在,同時運行,爭取更多的CPU資源。多線程機制是指可以同時運行多個程序塊,使程序運行的效率變得更高。
JAVA中線程的實現
在JAVA中要想實現多線程程序有兩種手段:1)繼承Thread類;2)實現Runnable接口。在JAVA中,所有線程都是同時啓動的,哪個線程先搶佔到了CPU資源,哪個線程就先運行。
由於JAVA的垃圾回收機制,其實每個JAVA程序運行時至少會啓動兩個線程,一個是main線程,另一個是垃圾收集線程。
繼承Thread類
Thread類是在java.lang包中定義的。利用Thread類實現多線程的方法如下:
- 創建一個線程子類繼承Thread類,並複寫其run()方法,此方法是線程的主體;
- 實例化這個子類,調用start()方法,啓動線程。
舉個例子:
class MyThread extends Thread {
private String name = null;
public MyThread(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(name + "運行,i = " + i);
}
}
}
public class ThreadDemo01 {
public static void main(String args[]) {
MyThread mt1 = new MyThread("線程 A - ");
MyThread mt2 = new MyThread("線程 B - ");
mt1.start();
mt2.start();
}
}
程序運行的結果:線程A跟線程B交替着運行(可能的一種可能)
線程 A - 運行,i = 0
線程 B - 運行,i = 0
線程 B - 運行,i = 1
線程 B - 運行,i = 2
線程 A - 運行,i = 1
線程 B - 運行,i = 3
線程 A - 運行,i = 2
線程 B - 運行,i = 4
線程 A - 運行,i = 3
線程 B - 運行,i = 5
線程 A - 運行,i = 4
線程 B - 運行,i = 6
線程 A - 運行,i = 5
線程 B - 運行,i = 7
線程 A - 運行,i = 6
線程 B - 運行,i = 8
線程 B - 運行,i = 9
線程 A - 運行,i = 7
線程 A - 運行,i = 8
線程 A - 運行,i = 9
實現Runnable接口
Runnable是一個接口,裏面定義個一個抽象方法run()。利用Runnable接口實現多線程的方法如下:
- 創建一個類實現Runnable接口,並複寫其中的run()方法,此方法是線程的主體;
- 實例化實現Runnable接口的對象,作爲參數傳遞到Thread的構造方法中,實例化Thread類;
- 調用Thread類的start()方法啓動線程。
舉個例子:
class MyThread implements Runnable {
private String name = null;
public MyThread(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(name + "運行,i = " + i);
}
}
}
public class ThreadDemo02 {
public static void main(String[] args) {
MyThread mt1 = new MyThread("線程 A - ");
MyThread mt2 = new MyThread("線程 B - ");
Thread t1 = new Thread(mt1);
Thread t2 = new Thread(mt2);
t1.start();
t2.start();
}
}
程序運行的結果:線程A跟線程B交替着運行(可能的一種可能)
線程 A - 運行,i = 0
線程 B - 運行,i = 0
線程 B - 運行,i = 1
線程 B - 運行,i = 2
線程 B - 運行,i = 3
線程 B - 運行,i = 4
線程 B - 運行,i = 5
線程 B - 運行,i = 6
線程 B - 運行,i = 7
線程 B - 運行,i = 8
線程 B - 運行,i = 9
線程 A - 運行,i = 1
線程 A - 運行,i = 2
線程 A - 運行,i = 3
線程 A - 運行,i = 4
線程 A - 運行,i = 5
線程 A - 運行,i = 6
線程 A - 運行,i = 7
線程 A - 運行,i = 8
線程 A - 運行,i = 9
Thread類與Runnable接口
雖然Thread類和Runnable接口都可以實現多線程,但是開發中建議使用Runnable接口,原因是Runnable接口具有以下優勢:
- Thread類是需要繼承的,其必定會收到JAVA單繼承的限制,而Runable接口則不受此限制,JAVA允許實現多個接口;
- Runnable接口中的線程主體代碼能夠被多個線程共享,實現資源的共享。
線程的狀態
任何線程都具有5種狀態,即創建,就緒,運行,阻塞,終止。線程狀態之間的轉移可以用下圖表示:
1. 創建狀態
在程序中用構造方法創建一個線程對象後,新的線程對象就處於創建狀態。此時,它已經有了相應的內存空間,只是還沒運行起來。
2. 就緒狀態
新建線程後,調用Thread類的start()方法就可以啓動線程。當線程啓動時,線程進入就緒狀態,進入線程隊列中排隊,等待CPU的時間片。
3. 運行狀態
當就緒狀態的線程獲得CPU調度後,線程就進入運行狀態。此時,會自動執行線程對象run()方法中的代碼。
4. 堵塞狀態
一個正在執行的線程在某些特殊條件下,如認爲掛起或者IO耗時操作,會讓出CPU中止自己的執行,進入堵塞狀態。如果調用sleep(),suspend(),wait()等方法,線程也會進入堵塞狀態。堵塞時,線程是不能進入排隊隊列的,只有當引起嘚瑟的原因被消除後,線程纔可以進入就緒狀態,等待CPU的重新調度。
5. 死亡狀態
線程調用stop()方法時或者run()方法執行結束後,即進入死亡狀態。處於死亡狀態的線程是不具有繼續運行的能力的。
線程操作的相關方法
序號 | 方法名稱 | 類型 | 作用描述 |
---|---|---|---|
1 | public Thread(Runnable target) | 構造 | 接收Runnable接口子類對象,實例化Thread對象 |
2 | public Thread(Runnable target,String name) | 構造 | 接收Runnable接口子類對象,實例化Thread對象,並設置線程名稱 |
3 | public Thread(String name) | 構造 | 實例化Thread對象,並設置線程名稱 |
4 | public static Thread currentThread() | 普通 | 返回目前正在執行的線程 |
5 | public final String getName() | 普通 | 返回線程的名稱 |
6 | public final getPriority() | 普通 | 返回線程的優先級 |
7 | public boolean isInterrupted() | 普通 | 判斷目前線程是否可被打斷 |
8 | public final boolean isAlive() | 普通 | 判斷線程是否在活動 |
9 | public final void join() throws InterruptedException | 普通 | 等待線程死亡 |
10 | public final synchronized void join(long millis) throws InterruptedException | 普通 | 等待millis毫秒後,線程死亡 |
11 | public void run() | 普通 | 線程主體方法 |
12 | public final void setName(String name) | 普通 | 設定線程名稱 |
13 | public final void setPriority(int newPriority) | 普通 | 設定線程優先級 |
14 | public static void sleep(long millis) throws InterruptedException | 普通 | 使目前正在執行的線程休眠millis毫秒 |
15 | public void start() | 普通 | 開始執行線程 |
16 | public String toString() | 普通 | 返回代表線程的字符串 |
17 | public static void yied() | 普通 | 將目前正在執行的線程暫停,允許其他線程執行 |
18 | public final void setDaemon(boolean on) | 普通 | 將一個線程設置成後臺運行 |
BR~
Jianwei Wang