JAVA之多執行緒概念及其幾種實現方法優劣分析
1. 多執行緒
程式:指令集,靜態的概念
程序:作業系統調動程式,是程式的一次動態執行過程,動態的概念
執行緒:在程序內的多條執行路徑
Ps:單核的話程序都是虛擬模擬出來的,多核處理器才可以執行真正的多執行緒
單核通過CPU排程時間片實現虛擬模擬的多執行緒,比如執行main函式和GC在底層就是多執行緒,你執行你的,我執行我的
一個程序內部的執行緒共享相同的記憶體單元,可以訪問相同的變數和物件,所以存在併發控制問題
執行緒和程序的區別:
1. 根本區別:程序是資源分配的單位,而執行緒是排程和執行的單位
2. 所處環境:多程序是指作業系統中可以有多個程序,多執行緒是同一個程序中有多個順序流同時執行
3. 切換開銷:每個程序擁有自己獨立的程式碼和資料空間(程序上下文),程序切換開銷大,同一個程序內的執行緒因為是共享的程序的共享資料,所以執行緒切換的開銷很小
4. 分配記憶體:系統會為每個程序分配不同的記憶體區域,而卻不會為執行緒分配,執行緒使用的是程序的資源
多執行緒的實現方法:
方法1:繼承Thread類
Rabbit.java
package 多執行緒; /** * @author:yb * @version 建立時間:2018-12-24 下午4:14:16 類說明 */ /* * 模擬龜兔賽跑 * 1.建立多執行緒:繼承Thread+重寫run()執行緒體 * 2.使用執行緒:建立子類物件+物件呼叫start()*/ public class Rabbit extends Thread { // 執行緒體 public void run() { for (int i = 1; i <= 100; i++) { System.out.println("兔子跑了" + i + "步"); } } } class Tortoise extends Thread { // 執行緒體 public void run() { for (int i = 1; i <= 100; i++) { System.out.println("烏龜跑了" + i + "步"); } } }
RabbitApp.java
package 多執行緒; /** * @author:yb * @version 建立時間:2018-12-24 下午4:20:53 類說明 */ public class RabbitApp { public static void main(String[] args) { // 建立子類物件 Rabbit rab = new Rabbit(); Tortoise tor = new Tortoise(); // 呼叫start方法,不用呼叫run方法這個執行緒體 rab.start(); tor.start(); /* * 為什麼輸出會是兔子跑了兩步烏龜才開始跑呢? * 因為是虛擬模擬實現的多執行緒,在底層cpu的按照時間片的輪轉排程的,時間片先是給兔子這個物件 * 它先跑兩部,然後時間片時間到了,cpu把時間片給烏龜,然後烏龜開始跑 * 實現的是虛擬的多執行緒(CPU輪流排程) * 如果是多核計算機的話,那才是真正的多執行緒2 */ } }
分析直接繼承Thread類這種方法的優缺點:
缺點:因為java的單繼承,多實現,當我們一開始繼承了其他類的時候,就不能繼承Thread類了
優點:好像沒有什麼優點
為了避免這一情況,我們通過Runnable介面實現多執行緒
所以我們有了方法2:通過Runnable介面實現多執行緒
方法2:通過Runnable介面實現多執行緒
在這裡使用了一種設計模式:靜態代理,關於靜態代理可以參考我的這篇部落格:https://www.cnblogs.com/yinbiao/p/10169851.html
Programmer.java:
package 多執行緒; /** * @author:yb * @version 建立時間:2018-12-25 下午7:05:34 類說明 */ /* * 使用Runnabke建立執行緒 * 1.類要實現Runnable介面+重寫run方法體 -->真實角色 * 2.建立多執行緒 使用靜態代理的設計模式 * 1)建立真實角色 * 2)建立代理角色+對真實角色的引用 * 3)呼叫start啟動執行緒 */ public class Programmer implements Runnable { // 重寫run方法體 public void run() { for (int i = 0; i < 1000; i++) { System.out.println("第" + i + "次敲Hello world"); } } }
programmerApp.java:
package 多執行緒; /** * @author:yb * @version 建立時間:2018-12-25 下午7:05:52 類說明 */ public class ProgrammerApp { public static void main(String[] args) { // 1)建立真實角色 Programmer pro = new Programmer(); // 2)建立代理角色+對真實角色的引用 Thread proxy = new Thread(pro); // 3)呼叫start啟動執行緒 proxy.start(); // 另外一個執行緒,因為main函式也算是一個執行緒 for (int i = 0; i < 1000; i++) { System.out.println("第" + i + "次開啟wegame"); } } }
優點:
1.避免了單繼承
2.方便共享資源,同一份資源,多個代理訪問
END!