1. 程式人生 > 其它 >java建立執行緒的四種方法

java建立執行緒的四種方法

第一種: 通過繼承Thread類建立執行緒

第二種: 通過實現Runnable介面建立執行緒

這兩種早已爛記於心,這裡就不作過多的介紹, 主要介紹其原始碼

Thread類 implements Runnable

thread空執行緒的run方法 是判斷target是否存在實,再執行target例項中的run方法

public void run(){
    if(this.target != null){
           this.target.run();
     }
}

通過實現Runnable介面, 並且通過thread建構函式建立執行緒的方法

Runnable runnable = new
Runnable(){...重寫run方法}; Thread thread_one = new Thread(runnable); Thread thread_two = new Thread(runnable);

如果建立多個執行緒, 實質是多個執行緒引用同一個target 例項

對比兩種方式的區別:

  通過繼承Thread類實現多執行緒的方式由於單繼承的侷限性, 不能再繼承其他類, 只能完成各自的任務

  通過實現Runnable介面實現多執行緒的方式能更好的做到併發完成同一個任務, 因為訪問的是同一個target, 實現了共享資料

總之,在大多數情況下,都偏向於通過實現Runnable介面建立多執行緒

第三種: 使用Callable介面 和 FutureTask類建立執行緒

由於Thread類和Runnbale介面中的run方法沒有返回值, 所以這兩種方式不能獲取非同步執行的結果

Callable介面

package java.util.concurrent;
@FunctionalInterface
public interface Callable<V>{
    V call() throws Exception;
}

@FunctionalInterface 註解標註在介面上, 表示此介面為"函式式介面"

函式式介面: 只有一個抽象方法的介面

此註解只是方便編譯器進行檢查, 不加也不會影響. 如果加了註解但該介面不是函式式介面,編譯器會報錯

Callable介面是泛型介面 ,也是函式式介面

call()抽象方法還有一個Exception的異常宣告, 容許方法內的異常直接丟擲,並且可以不予捕獲

Future介面, RunnableFuture介面,以及FutureTask實現類都是位於 java.util.concurrent包下

V get() 用於阻塞性得到非同步執行的結果. 此方法是阻塞性的,非同步未執行完會處於阻塞狀態

Object outcome  用於儲存call()方法的非同步執行結果. get()會獲取

建立執行緒的具體步驟

class ReturnableTask implements Callable<Long>{
      public long call() throws Exception{
             //執行緒要執行的程式碼
     }      
}    

public static void main(String args[]) throws InterruptedException{
    ReturnableTask task  = new new ReturnableTask();
     Futuretask<Long> FutureTask = new Futuretask<Long>(task);
    Thread thread = new Thread(FutureTask,"returnableThread");  
    thread.start();
    System.out.println(FutureTask.get());   //得到非同步執行結果
}

下圖為具體實現過程

兩個執行緒處於併發狀態, 預設非同步執行

看起來兩個執行緒是同時進行,實質上是不是, 單個程序在同一時間只能執行一個程序,由於分給執行緒的時間片非常短(執行緒切換毫秒級),所以以為是同時

併發執行的訊息通訊機制分為同步和非同步, 這些就不做過多解釋

總之,圖上的兩個執行緒不是同時執行

第四種: 通過執行緒池建立執行緒

通過Thread建立執行緒在執行完就被銷燬了, 不可服用. 在高併發場景中, 頻繁建立執行緒是非常消耗資源的, 通過執行緒池建立執行緒可以對已經建立好的執行緒進行復用

Executors 靜態工廠類 用於建立不同的執行緒池 java.util.concurrent;

//建立一個包含三個執行緒的執行緒池
private static ExecutorService pool = Executors.newFixedThreadPool(3);

Executor介面

  void executo(Runnable command);    //執行Runnable型別

ExecutorService<T> extends Executor

  <T> Future<T> submit(Callable<T> task)   //提交callable型別以執行

  Future<?> submit(Runnable task)      //提交Runnable型別以執行

具體實現

main
Future future  = pool.submit(new RuturnableTask());
Long result = (Long) future.get();     //得到非同步執行的結果

execute() 與 submit() 執行執行緒方法的區別

execute()只能執行Runnable, 並且無返回值

submit() 既能執行Runnable又能執行callable, 並且有返回值

注: 實際生產環境中禁止使用Executors建立執行緒池