了解進程與線程:
進程:
當一個程序進入內存運行時,即變成一個進程。進程是處于運行過程 中的程序,并且具有一定的獨立功能,進程是系統進行資源分配和調度的一個獨立單 位一般而言,進程包含如下三個特征:
- 獨立性:進程是系統中獨立存在的實體,它可以擁有自己獨立的資源,每一個進程都擁有自己私有的地址空間。在沒有經過進程本身允許的情況下,一個用戶進程不可以直接訪問其他進程的地址空間。
- 動態性:進程與程序的區別在于,程序只是一個靜態的指令集合,而進程是一個 正在系統中活動的指令集合。在進程中加入了時間的概念。進程具有自己的生命 周期和各種不同的狀態,這些概念在程序中都是不具備的。
- 并發性:多個進程可以在單個處理器上并發執行,多個進程之間不會互相影響。
線程:
多線程擴展了多進程的概念,使得同一個進程可以同時并發處理多個任務。線程 (Thread)也被稱作輕量級進程(Lightweight Process),線程是進程的執行單元。 就像進程在操作系統中的地位一樣,線程在程序中是獨立的、并發的執行流。當進程被初始化后,主線程就被創建了。對于絕大多數的應用程序來說,通常僅要求有一個主線程,但也可以在該進程內創建多條順序執行流,這些順序執行流就是線程,每個線程也是互相獨立的。
線程是進程的組成部分,一個進程可以擁有多個線程,一個線程必須有一個父進程。 線程可以擁有自己的堆棧、自己的程序計數器和自己的局部變量,但不擁有系統資源,它與父進程的其他線程共享該進程所擁有的全部資源。因為多個線程共享父進程里的全部資源,因此編程更加方便;但必須更加小心,因為需要確保線程不會妨礙同 一進程里的其他線程線程可以完成一定的任務,可以與其他線程共享父進程中的共享 變量及部分環境,相互之間協同來完成進程所要完成的任務。
簡潔來說:
操作系統可以同時執行多個任務,每個任務就是進程;進程可以同時執行多個 任務,每個任務就是線程。
Java 語言中主要兩種實現線程的方式:
- 繼承Thread類創建線程類
- 實現Runnable接口創建線程類
一.繼承Thread類創建線程類
實現步驟:
? 定義類繼承Thread類,并重寫Thread類的run()方法,該run()方法的方法體就代表了線程需要完成的任務。因此把run()方法稱為線程執行體。
? 創建Thread 子類的實例,即創建了線程執行體。
? 調用線程對象的start() 方法來啟動該線程。
如下示例:
public class ExtendsThreadDemo {public static void main(String[] args) {MyThread1 myThread1 = new MyThread1();MyThread1 myThread12 = new MyThread1();// 調用start方法方可啟動線程// 不能調用run()方法,run方法只是thread的一個普通方法,還是在主線程里執行。//啟動線程myThread1.start();myThread12.start(); }
}//繼承Thread類創建線程類 繼承Thread類,重寫run方法
class MyThread1 extends Thread{@Overridepublic void run() {System.out.println("線程id--"+ getId());System.out.println("線程名稱--"+ getName());for (int i = 0; i < 10; i++) {System.out.println("線程id:"+getId()+" "+i);}}
}
你會發現線程的執行順序不太固定,是沒有固定順序的,結果示例:
二.實現Runnable 接口創建線程類
實現步驟:
? 定義類實現Runnable接口,并重寫Runnable接口的run()方法,該run()方法的 方法體就代表了線程需要完成的任務。
? 創建Runnable實現類的實例,并以此實例作為Thread的target來創建Thread對象,該Thread對象才是真正的線程對象。
? 用該Thread對象的start()方法來啟動該線程。
如下示例:
public class RunnableThreadDemo {public static void main(String[] args) {//創建Runnable實現類的實例MyThread2 myThread2= new MyThread2();//創建Thread類,并把Runnable實現類的實例作為參數Thread thread1 = new Thread(myThread2);//傳入一個Runnable 的實現類Thread thread2 = new Thread(myThread2);//啟動線程thread1.start();thread2.start();}
}class MyThread2 implements Runnable{@Overridepublic void run() {// 實現Runnable接口的,無法直接使用getId(),getName()等方法// 需要使用Thread.currentThread() 來獲取到當前對象才行System.out.println("線程id--"+ Thread.currentThread().getId());System.out.println("線程名稱--"+ Thread.currentThread().getName());for (int i = 0; i < 10; i++) {System.out.println("線程id:"+ Thread.currentThread().getId()+" "+i);}}
}
結果如下: