1. 程式人生 > >第一章01 Java多執行緒程式設計

第一章01 Java多執行緒程式設計

一、主要內容

A. 執行緒與程序

B. 多執行緒的實現(繼承Thread類實現)

C. 多執行緒的實現(Runnable介面實現)

D. 多執行緒的實現(兩種執行緒實現方式的區別)

E. 多執行緒的實現(Callable介面實現)

二、分塊講解

A. 執行緒與程序

最早的時候DOS系統:只要電腦中毒,則電腦就宕機。傳統的DOS系統屬於單程序作業系統,即在同一個時間段內,只允許有一個程式執行。

Windows時代的改變:電腦即使中毒,也可以使用。但是執行速度會變慢。在一個CPU、一塊資源的情況下,程式利用一些輪轉演算法,可以讓一個資源在一個時間段上同時處理多個程式(程序),在一個時間點上只允許一個程序去執行。

程序與執行緒的關係:一個程序可以劃分為多個執行緒,執行緒的操作快於程序,多執行緒的操作效能優於多程序操作。所有的執行緒都一定在程序的基礎之上進行劃分。程序消失,則執行緒一定消失(執行緒永遠依附於程序存在)。

B. 多執行緒的實現(繼承Thread類實現)

範例1:

//定義Mythread類繼承Thread類
class Mythread extends Thread{
    String name;
    public Mythread(String name){
        this.name = name;
    }
    @Override
    public void run(){
        for(int i = 0;i<10;i++){
            System.out.println(name+i);
        }
    }
}
//在主類中生成Mythread物件並呼叫start()啟用執行緒
public class mainDemo{

    public static void main(String[] args) {
        Mythread mt1 = new Mythread("張三");
        Mythread mt2 = new Mythread("李四");
        Mythread mt3 = new Mythread("王五");
        mt1.start();
        mt2.start();
        mt3.start();
    }
}
//執行結果(不唯一,只要張三 李四 王五 交替出現即為正確):
/*
李四0
王五0
張三0
張三1
張三2
張三3
張三4
張三5
張三6
張三7
張三8
張三9
王五1
李四1
李四2
王五2
王五3
王五4
王五5
李四3
王五6
李四4
李四5
李四6
李四7
李四8
王五7
王五8
李四9
王五9
*/

範例2:直接呼叫run方法會出現什麼結果呢?

//如果在主方法中直接呼叫run方法,會出現什麼結果呢?
public class mainDemo{

    public static void main(String[] args) {
        Mythread mt1 = new Mythread("張三");
        Mythread mt2 = new Mythread("李四");
        Mythread mt3 = new Mythread("王五");
        mt1.run();
        mt2.run();
        mt3.run();
    }
}
//執行結果(唯一):
/*
張三0
張三1
張三2
張三3
張三4
張三5
張三6
張三7
張三8
張三9
李四0
李四1
李四2
李四3
李四4
李四5
李四6
李四7
李四8
李四9
王五0
王五1
王五2
王五3
王五4
王五5
王五6
王五7
王五8
王五9
*/

C. 多執行緒的實現(Runnable介面實現)

Runnable介面的定義

@FunctionalInterface
public interface Runnable{
    public void run();
}

範例1:

//定義Mythread類實現Runnable介面
class Mythread implements Runnable{
    String name;
    public Mythread(String name){
        this.name = name;
    }
    @Override
    public void run(){
        for(int i = 0;i<10;i++){
            System.out.println(name+i);
        }
    }
}
//由於Thread的構造方法為:public Thread(Runnable target),因此,可以通過傳入Runnable介面並呼叫Thread的start方法啟用執行緒

public class mainDemo{

    public static void main(String[] args) {
        Mythread mt1 = new Mythread("張三");
        Mythread mt2 = new Mythread("李四");
        Mythread mt3 = new Mythread("王五");
        new Thread(mt1).start();
        new Thread(mt2).start();
        new Thread(mt3).start();
    }
}
//執行結果(不唯一,只要張三 李四 王五 交替出現即為正確):
/*
李四0
王五0
張三0
張三1
張三2
張三3
張三4
張三5
張三6
張三7
張三8
張三9
王五1
李四1
李四2
王五2
王五3
王五4
王五5
李四3
王五6
李四4
李四5
李四6
李四7
李四8
王五7
王五8
李四9
王五9
*/

範例2: 使用匿名物件實現多執行緒

public class mainDemo{

    public static void main(String[] args) {
        String name = "張三";
        new Thread(new Runnable(){
            @Override
            public void run(){
                for(int i = 0;i<10;i++){
                System.out.println(name+i);
                }
            }
        }).start();
    }
}
//執行結果
/*
張三0
張三1
張三2
張三3
張三4
張三5
張三6
張三7
張三8
張三9
*/

範例3: 使用Lamda表示式實現多執行緒(JDK1.8)

public class mainDemo{

    public static void main(String[] args) {
        String name = "張三";
        new Thread(()->{
            for(int i = 0;i<10;i++){
            System.out.println(name+i);
            }
        }).start();
    }
}
//執行結果
/*
張三0
張三1
張三2
張三3
張三4
張三5
張三6
張三7
張三8
張三9
*/