一、線程依賴於進程而存在。
進程,正在運行的程序。是系統進行資源分配和調用的獨立單位。每一個進程都有它自己的內存空間和系統資源。
二、多進程的意義:
單進程的計算機只能做一件事,而現在都可以做多件事情,支持多進程,可以在一個時間段內執行多個任務。 提高CPU的使用率~
問題:
一邊玩遊戲,一邊聽音樂是同時進行嗎?
不是。因爲單COU在某一個時間點上只能做一件事情。(多核可以實現,但是會有很多進程,就不行了)
而我們在玩遊戲,或者聽音樂的時候,是CPU在做着程序間的高效切換讓我們覺得是同時進行的。 切換時間超短。
三、線程:
1.在同一個進程內又可以執行多個任務,而每一個任務我們就可以看成是一個線程。
2.是程序的執行單元,執行路徑。是程序使用CPU的最基本的單位。
a.如果程序只有一條執行路徑,那麼該程序就是單線程程序
b.如果程序有多條執行路徑,那麼該程序就是多線程程序
四、多線程的意義:
1.多線程的存在,不是提高程序的執行速度。其實是爲了提高應用程序的使用率。
2.程序的執行其實都是在搶CPU的資源,CPU的執行權。
3.多個進程是在搶這個資源,而其中的某一個進程如果執行路徑比較多,就會有更高的機率搶到CPU的執行權。
4.我們是不敢保證哪一個線程能夠在哪個時刻搶到,所以線程的執行有隨機性。
五、並行和併發:
A:並行是邏輯上同時發生,指在某一個時間內同時運行多個程序
B:併發是物理上同時發生,指在某一個時間點同時運行多個程序
六、Java運行原理
java命令會啓動java虛擬機,啓動JVM,等於啓動了一個應用程序,也就是啓動了一個進程。該進程會自動啓動一個“主線程”,然後主線程去調用某個類的main方法。所以main方法運行在主線程中。在此之前的所有程序都是單線程。
jvm虛擬機至少啓動了垃圾回收線程和主線程(調用main方法),所以是多線程的
垃圾回收是以防出現內存溢出
C/C++可以去調用系統功能並創建進程,然後由Java去調用,實現多線程程序(Java不可以直接調用系統功能)
七、繼承Thread(線程)類
a.自定義類繼承Thread類。
b.在自定義類中重寫run()方法(run()方法執行需要被線程執行的代碼)。
c.創建對象。
d.啓動線程。
public class MyThread extends Thread{
//比較耗時的程序才執行線程
public void run() {
//添加需要被線程的代碼
}
}
public class MyThreadDemo {
public static void main(String[] args) {
MyThread my = new MyThread();
//my.run(); 直接調用無線程效果
//若直接調用run()方法就相當於普通方法的調用
//因此還有另一個方法start();
//run()僅僅是封裝被線程執行的代碼,直接調用是普通方法
//start()首先啓動了線程,然後由jvm調用線程的run()方法
my.start();
//my.start();再此調用,相當於my線程被調用了兩次,出現IllegalThreadStateException:非法的線程狀態
//若想兩個線程啓動,需創建兩個對象。
MyThread my1 = new MyThread();
MyThread my2 = new MyThread();
my1.start();
my2.start();
}
}
public final String getName(); //該方法可以獲取線程的名稱,在自定義類中的 run方法中使用 默認顯示Thread-0,Thread-1...
八、自定義線程的名稱兩種方法:
a.public final String setName(); //該方法可以自定義線程的名稱,在主類中調用my1.setName("***");
b.通過在自定義類中加入帶參構造方法如public MyThread(String name) {super(name);} ,然後創建對象時直接加入名稱如MyThread
my1 = new MyThread(“第一個線程”);
九、線程調度(兩種)以及設置線程優先級:
1.分時調度模型。所有線程輪流使用CPU的使用權,平均分配每個線程佔用CPU的時間片
2.搶佔式調度模型。優先讓優先級高的線程使用CPU,若相同,則隨機選擇,優先級高的線程獲取CPU的時間片相對多一些。
Java使用的是搶佔式調度模型。
設置線程優先級:
public final int getPriority(); //返回線程對象的優先級。默認優先級是5。
public final void setPriority(); //設置線程的優先級。
MAX_PRIORITY最大優先級值是10
MIN_PRIORITY最小優先級是1
NORM_PRIORITY默認優先級是5
線程優先級別高僅僅表示線程獲取的CPU時間片的機率高,但是要在多次運行的時候才能看到比較好的效果。
十、線程控制:
父類(Thread)方法:
a.線程休眠
public static void sleep(long millis);
//指定毫秒內休眠
//自定義類中run()裏調用 Thread.sleep(millis);
b.線程加入
public final void join();
//等待該線程終止,其他線程再開始
//主類中調用
c.線程禮讓
public static void yield();
//暫停當前正在執行的線程對象,並執行其他線程
//自定義類中調用
//讓多個線程的執行更和諧,但不能保證一個線程一次。
d.後臺線程
public
final void setDaemon(boolean on);
//將該線程標記爲守護線程或用戶線程,當正在運行的線程都是守護線程時(即主線程滅亡,守護線程隨之消失),Java虛擬機退出
//該方法必須在啓動線程前調用
//主類中調用
e.中斷線程
public final void stop();
//該方法已過時,但還可以使用。不建議使用,顯示stop();
//多長時間線程沒有進行就結束了
//主類中調用
public void interrupt();
//把線程的狀態終止,拋出異常InterruptedException
十一、線程的生命週期
- 新建:創建線程對象
- 就緒:有執行資格,沒有執行權
- 運行:有執行資格,有執行權權
- 阻塞:由於一些操作讓線程處於該狀態。沒有執行資格,沒有執行權,而另一些操作卻可以把它激活,激活後處於就緒狀態
- 死亡:線程對象變成垃圾,等待回收
新建→(start())→就緒→(獲取到了CPU的執行權)→運行→(run()結束、中斷線程)→死亡(等待被回收)
運行時也許會有阻塞sleep(),wait(),時間(sleep())到後或喚醒(notify())後繞到就緒狀態,再運行
被別的線程搶到執行權就回到就緒狀態
十二、實現多線程的方式:
方式一:繼承Thread類
a.自定義類繼承Thread類
b.在自定義類中重寫run()方法
c.創建自定義類的對象
d.啓動線程的對象
方式二:實現Runnable接口(大多數使用)
a.自定義類實現Runnable接口
b.在自定義類中重寫run()方法
c.創建自定義類的對象
d.創建Thread類的對象,並把c步驟創建的對象作爲構造參數傳遞
優點:避免由於單繼承帶來的侷限性
適合多個程序的代碼處理同一個資源的情況,把線程同程序的代碼、數據有效分離,較好的體現了面向對象的設計思想。
多線程是java學習進階的重要知識,循序漸進的學習會收穫很多