一、背景
在沒有學習Java多執行緒以前,總覺得多執行緒是個很神祕的東西,只有那些大神才能駕馭,新年假期沒事就來學習和了解一下Java的多執行緒,本篇部落格我們就來從頭說一下多執行緒到底是怎麼回事。
二、概述
1.程式的概念
每一個正在執行的程式都是一個程式,它是系統進行資源分配和呼叫的獨立單位。且 每一個程式都有自己的記憶體空間和系統資源。
2.執行緒的概念
是程式中的單個順序控制流,是一條執行路徑。每個程式都可以擁有一個或者多個執行緒。各個執行緒之間都共享所屬的那個程式的記憶體空間和系統資源。
3.單執行緒和多執行緒程式的辨別方式
如果一個程式只有一條執行路徑,則稱為單執行緒程式。 如果一個程式有多條執行路徑,則稱為多執行緒程式(經典應用程式:掃雷、迅雷下載)。
廢話不多說,我們直接上圖來解釋
4.站線上程的角度來解釋Java程式執行某各類的main方法
首先java 命令會啟動 java 虛擬機器,即啟動 JVM,等於啟動了一個應用程式,也就是啟動了一個程式。該程式會自動啟動一個 “主執行緒” ,然後主執行緒去呼叫某個類的 main 方法。所以 main方法執行在主執行緒中。在此之前的所有程式都是單執行緒的。
三、多執行緒程式的實現方式
1.方式一:繼承Thread類,重寫run方法。
1 package cn.hafiz; 2 3 /* 4 *多執行緒demo 5 */ 6 public class MyThread extends Thread { 7 8 @Override 9 public void run() { 10 for (int x = 0; x < 200; x++) { 11 System.out.println(x); 12 } 13 } 14 15 }
幾個需要注意的問題:
為什麼要重寫run()方法?
答:我們只有把想要線上程中執行的程式碼寫在run方法裡才能啟動執行緒進行執行。
啟動執行緒使用的是那個方法?
答:啟動使用的是start方法。
執行緒能不能多次啟動?
答:一個執行緒只能啟動一次,否則會報IllegalThreadStateException異常。
run()和start()方法的區別?
答:run()方法是普通的方法呼叫,並不是啟用執行緒,而start方法是首先啟動一個新的執行緒,然後執行run()方法裡面的程式碼。
2.方式二:實現Runnable介面
1 package com.hafiz; 2 3 public class MyRunnable implements Runnable { 4 5 @Override 6 public void run() { 7 for (int x = 0; x < 100; x++) { 8 System.out.println(Thread.currentThread().getName() + ":" + x); 9 } 10 } 11 12 }
該實現方式優點:
可以避免由於Java單繼承帶來的侷限性。 適合多個相同程式的程式碼去處理同一個資源的情況,
把執行緒同程式的程式碼,資料有效分離,較好的體現了物件導向的設計思想。
四、執行緒基本操作
1.獲取和設定執行緒名稱
public final String getName();
public final void setName(String name);
其實通過構造方法也可以設定執行緒名稱.
public static Thread currentThread():獲取任意方法所在的執行緒名稱.
2.執行緒排程
1).之所以出現執行緒排程是因為計算機只有一個 CPU,那麼 CPU 在某一個時刻只能執行一條指令,執行緒只有得到 CPU時間片,也就是使用權,才可以執行指令。
2).執行緒的兩種排程模型(Java使用的是搶佔式排程模型).
分時排程模型:所有執行緒輪流使用 CPU 的使用權,平均分配每個執行緒佔用 CPU 的時間片。
搶佔式排程模型:優先讓優先順序高的執行緒使用 CPU,如果執行緒的優先順序相同,那麼會隨機選擇一個,優先順序高的執行緒獲取的 CPU 時間片相對多一些。
獲取和設定執行緒優先順序的方法:
public final int getPriority();
public final void setPriority(int newPriority);
3.執行緒控制
執行緒休眠:public static void sleep(long millis);
執行緒加入:public final void join();
執行緒禮讓:public static void yield();
設定是否為守護執行緒(當所有的執行緒都為守護執行緒就不具有搶佔CPU執行權的資格):
public final void setDaemon(boolean on);
上圖中的關羽和張飛可以看成守護執行緒,當劉備主執行緒消亡以後,兩者都不可能再具有獲得CPU執行權的資格。
中斷執行緒:
public final void stop();(已過時,直接將虛擬機器退出)
public void interrupt();(建議使用,是中斷執行緒並且丟擲一個InterruptedException異常,虛擬機器不會退出,執行緒之後的程式碼會繼續執行)
4.執行緒生命週期
1).建立:新建執行緒物件。
2).就緒:執行緒物件已經啟動,已經具有獲得CPU的資格,但沒有獲取執行權。
3).執行:獲得了CPU的執行權,執行執行緒。
4).阻塞:沒有CPU的執行權,只能等待會到就緒狀態。
5).死亡:執行緒程式碼執行完畢,執行緒消亡。
嫌文字不好理解,直接上圖說明: