首頁 > Java > Java基礎 > 主體

java中實作多線程的幾種方式

王林
發布: 2019-12-04 16:43:08
原創
4813 人瀏覽過

java中實作多線程的幾種方式

Java多執行緒的使用有三種方法:繼承Thread類別、實作Runnable介面和使用Callable和Future建立執行緒。

一、繼承Thread類別

實作方式很簡單,只需要建立一個類別去繼承Thread類別然後重寫run方法,在main方法中呼叫該類別實例物件的start方法即可實作多執行緒並發。程式碼:

public class MyThread extends Thread {
    @Override
    public void run(){        
        super.run();
        System.out.println("执行子线程...");
    }
}
登入後複製

測試案例:

public class Test {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
        System.out.println("主线程...");
    }
}
登入後複製

運行結果:

java中實作多線程的幾種方式

當然,這裡的結果不代表執行緒的執行順序,執行緒是並發執行的,如果多運行幾次,列印順序可能會不一樣。在多執行緒的運行過程中,CPU是以不確定的方式去執行執行緒的,故運行結果與程式碼的執行順序或呼叫順序無關,運行結果也可能不一樣。

免費影片教學推薦:java學習影片

這裡還有一個需要注意的點就是main方法中應該呼叫的是myThread的start方法,而不是run ()方法。呼叫start()方法是告訴CPU此執行緒已經準備就緒可以執行,然後係統有時間就會來執行其run()方法。

而直接呼叫run()方法,則不是非同步執行,而是等同於呼叫函數般依序同步執行,這就失去了多執行緒的意義了。

二、實作Runnable介面

這種方式的實作也很簡單,就是把繼承Thread類別改為實作Runnable介面。程式碼如下:

public class MyRunnable implements Runnable {    
    @Override
    public void run() {
        System.out.println("执行子线程...");
    }
}
登入後複製

測試案例:

public class Test {    
    public static void main(String[] args) {
        Runnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();
        System.out.println("主线程运行结束!");
    }
}
登入後複製

運行結果:

java中實作多線程的幾種方式

運行結果沒啥好說的,這裡main可以看到真正創建新線程還是透過Thread創建:

Thread thread = new Thread(runnable);
登入後複製

這一步Thread類別的作用就是把run()方法包裝成線程執行體,然後依然透過start告訴系統這個線程已經準備好了可以安排執行。

三、使用Callable和Future建立執行緒

#上面的兩種方式都有這兩個問題:

# 1.無法取得子執行緒的回傳值;

2、run方法不可以拋出例外。

為了解決這兩個問題,我們就需要用到Callable這個介面了。說到接口,上面的Runnable接口實作類別實例是作為Thread類別的建構子的參數傳入的,之後透過Thread的start執行run方法中的內容。但是Callable並不是Runnable的子接口,是個全新的接口,它的實例不能直接傳入給Thread構造,所以需要另一個接口來轉換一下。

Java5提供了Future介面來代表Callable介面裡call()方法的回傳值,並為Future介面提供了實作類別FutureTask,該實作類別的繼承關係如圖所示:

java中實作多線程的幾種方式

可以看到,這個實作類別不僅實作了Future接口,還實作了Runnable接口,所以可以直接傳給Thread建構子。

而關於FutureTask的建構子如下:

所以這裡面其實就是要比上一個方法再多一個轉換過程,最終一樣是透過Thread的start來建立新執行緒。有了這個思路,程式碼就很容易理解了:

import java.util.concurrent.Callable;
public class MyCallable implements Callable {    
int i = 0;    
@Override
    public Object call() throws Exception {
        System.out.println(Thread.currentThread().getName()+"  i的值:"+ i);        
        return i++; //call方法可以有返回值
    }
}
登入後複製

測試:

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class Test {
    public static void main(String[] args) {
        Callable callable = new MyCallable();        
        for (int i = 0; i < 10; i++) {
            FutureTask task = new FutureTask(callable);            
            new Thread(task,"子线程"+ i).start();            
            try {                //获取子线程的返回值
                System.out.println("子线程返回值:"+task.get() + "\n");
            }  catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
登入後複製

執行結果(部分):

java中實作多線程的幾種方式

##相關文章教學推薦:

java入門程式#

以上是java中實作多線程的幾種方式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!