1. 程式人生 > >JAVA之多執行緒概念及其幾種實現方法優劣分析

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!