Java基礎併發(一)之Runnable、Thread的使用

有關於線程與進程的區別請看操作系統之進程管理

文章是《Java編程思想》–Bruce Eckel著,陳昊鵬譯的《Thinking in Java》的學習筆記

線程可以驅動任務,如果要在線程上跑任務,那麼就需要一種描述任務的方式。這個方式可以有Runnable接口來提供,要想定義一個任務,只需要實現Runnable接口並編寫run()方法,使得該任務可以執行你的命令。

package ink.poesy.threadtest;

public class LiftOff implements Runnable{
    protected int countDown = 10;
    private static int taskCount = 0;
    //id用來區分多個線程,final一旦初始化之後就不希望被修改
    private final int id = taskCount++;
    public LiftOff(){}
    public LiftOff(int countDown){
        this.countDown  = countDown;
    }
    public String status(){
        return "#" + id + "("+
                (countDown > 0 ? countDown : "Liftoff!") + "),";
    }

    @Override
    public void run() {
        while (countDown-- > 0){
            System.out.println(status());
            Thread.yield();
        }
    }
}

Thread.yield();線程調度器(java線程機制的一部分,可以將CPU從一個線程轉移給另一個線程。意義:我已經執行完生命週期中最重要的不分了,此刻正式切換給其他任務執行一段時間的大好時機)。


注:當從Runnable導出一個類時,它必須具有run()方法,但這個方法並無特殊之處——它不會產生任何內在的線程能力。要實現線程行爲,必須顯示的將一個任務附着到線程上。看下面的2個例子來說明這個問題。

public class MainThread {
    public static void main(String[] args) {
        LiftOff launch = new LiftOff();
        launch.run();
        System.out.println("wwl");
    }
}

執行10次穩定的顯示
執行結果1
上面例子wwl始終顯示在最下面。下面這個例子不是

public class BasicThreads {
    public static void main(String[] args) {
        Thread t = new Thread(new LiftOff());
        t.start();
        System.out.println("wwl");
    }
}

執行結果
在這裏插入圖片描述
上面例子展示了使用Thread來驅動LiftOff對象。
Thread構造器只需要一個Runnable對象。調用Thread對象的start()方法爲該線程執行必須的初始化操作,然後調用Runable的run()方法,以便在這個新線程中啓動該任務。儘管start()看起來是產生了一個對長期運行的方法調用,但是從輸出中可以看到,start()迅速返回了,因爲wwl消息再倒計時完成之前就出現了。實際上,你產生的是對LiffOff.run()的方法調用,並且這個方法還沒有完成,但是因爲LiffOff.run()是由不同的線程執行的,因此你仍舊可以執行main()線程中的其他操作。
將Runnable對象轉變爲工作任務的傳統方式是把它提交給一個Thread構造器


下面是添加更多的線程驅動更多的任務。


第一次執行結果

Waiting for LiftOff!
#0(9),#4(9),#3(9),#2(9),#2(8),
#2(7),#2(6),#2(5),#2(4),#2(3),
#2(2),#2(1),#2(Liftoff!),#3(8),
#3(7),#3(6),#3(5),#3(4),#3(3),
#3(2),#3(1),#3(Liftoff!),#1(9),
#1(8),#1(7),#1(6),#1(5),#1(4),
#1(3),#1(2),#1(1),#1(Liftoff!),
#0(8),#0(7),#0(6),#0(5),#0(4),
#0(3),#0(2),#0(1),#0(Liftoff!),#4(8),
#4(7),#4(6),#4(5),#4(4),#4(3),#4(2),
#4(1),#4(Liftoff!),

第二次執行結果

Waiting for LiftOff!
#0(9),#4(9),#0(8),#4(8),#0(7),#4(7),
#0(6),#4(6),#0(5),#4(5),#0(4),#4(4),
#0(3),#4(3),#0(2),#4(2),#0(1),#4(1),
#0(Liftoff!),#4(Liftoff!),#1(9),#1(8),
#1(7),#1(6),#1(5),#1(4),#1(3),#1(2),
#1(1),#1(Liftoff!),#3(9),#3(8),#3(7),
#3(6),#3(5),#3(4),#3(3),#3(2),#3(1),
#3(Liftoff!),#2(9),#2(8),#2(7),#2(6),
#2(5),#2(4),#2(3),#2(2),#2(1),#2(Liftoff!),

輸出說明不同任務的執行在線程被換進換出時混在了一起。


以上內容如有爭議、指正,留言給我~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章