1. 程式人生 > >併發程式設計執行緒實現方式Thread,Runnable

併發程式設計執行緒實現方式Thread,Runnable

Thread,Runnable的區別

我們建立執行緒的方式一般來說有兩種,首先我們來看看兩種啟動執行緒方式的具體實現。

  1. 第一種繼承Thread類,實現run方法,最後呼叫start方法啟動執行緒。
  2. 第二種實現Runnable介面,實現run方法,然後呼叫Thread的有參構造方法,將Runnable的子類物件作為構造方法的引數建立一個Thread物件,最後呼叫start方法啟動執行緒。

從上面兩點來看就能知道這兩種方式的不同了。

  1. 首先,第一點,Thread是類,而Runnable是介面。java中不能同時繼承多個類,但是可以實現多個介面。所以相對Runnable來說,Thread方式在抽象開發上來說就侷限了一點。
  2. 其次是第二點,Runnable實現執行緒的方式需要將Runnable子類物件作為Thread有參構造方法的引數傳入,也就是說我們建立多個Thread物件,但是可以用同一個Runnable子類物件作為構造方法引數傳入,這樣多個執行緒訪問的就是同一個物件的資料和運行同樣的程式碼(也即是同一個任務)。而Thread要直接做到這一點就不行,當然了我說的是直接做到不行,通過其他方式中轉一下也是可以的(比如說:用靜態變數或者新建一個數據類物件傳入就可以達到訪問同一個變數),只不過這樣就相對麻煩了一些哈!

Thread執行緒實現

執行緒類:

package com.example;

/**
 * Created by PICO-USER on 2017/11/8.
*/ public class MyThread extends Thread { private int number = 5; @Override public void run() { super.run(); synchronized (this) { for (int i = 0; i < 6; i++) { synchronized (MyThread.class) { if (number > 0) { System.out
.print(getName() + " number = " + number + "\n"); number--; } } } } } }

主程式入口:

public class MyClass {

    public static void main(String[] args0) throws InterruptedException {

        Thread thread = null;
        for (int i = 0; i < 3; i++) {
            thread = new MyThread();
            thread.setName("Thread_" + i);
            thread.start();
        }
    }
}
輸出結果:


看看上面的結果,我們用的是非靜態變數,所以三個執行緒操作的是三個不同的物件的資料。但是Runnable方式的就不醬紫了(看下面)。

Runnable執行緒實現

package com.example;

/**
 * Created by PICO-USER on 2017/11/8.
 */
public class MyRunnable implements Runnable {
    public int number = 5;

    @Override
public void run() {
        String name = Thread.currentThread().getName();
        synchronized (this) {
            for (int i = 0; i < 6; i++) {
                if (number > 0) {
                    System.out.print(name + " number = " + number + "\n");
                    number--;
                }
            }
        }
    }
}

主程式入口:

package com.example;

import java.util.Properties;

public class MyClass {

    public static void main(String[] args0) throws InterruptedException {

        Runnable runnable = new MyRunnable();
        Thread thread = null;
        for (int i = 0; i < 3; i++) {
            thread = new Thread(runnable);
            thread.start();
        }
    }
}
輸出結果:


總結:很明顯,同樣的任務,輸出的結果卻是不一樣的。其實說到底,將執行緒跟類這兩個概念分開理解清楚,一切問題也就迎刃而解了。啟動執行緒是去執行任務,任務是run方法中的程式碼執行,那具體操作的資料,是類中的資料。Thread方式,啟動執行緒的是Thread,操作的資料和執行的任務還是在Thread的子類,而Runnable方式中,啟動執行緒的是Thread類,而操作的資料和執行的任務卻是在Runnable子類中。