中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java怎么創建線程及配合使用Lambda方式

發布時間:2021-08-24 15:06:29 來源:億速云 閱讀:157 作者:chen 欄目:開發技術

本篇內容介紹了“Java怎么創建線程及配合使用Lambda方式”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

目錄
  • 一、創建線程三種方式

    • 1.1 繼承Thread類創建線程類

    • 1.2 通過Runnable接口創建線程類

      • 使用Lambda表達式

    • 1.3 通過Callable和Future創建線程

      • 使用Lambda表達式

  • 二、創建線程的三種方式的對比

    • 2.1 實現Runnable、Callable接口的方式創建多線程

      • 2.2 繼承Thread類的方式創建多線程

        • 2.3 Runnable和Callable的區別

        一、創建線程三種方式

        1.1 繼承Thread類創建線程類

        • 定義Thread類的子類,并重寫該類的run方法,該run方法的方法體就代表了線程要完成的任務。因此把run()方法稱為執行體。

        • 創建Thread子類的實例,即創建了線程對象。

        • 調用線程對象的start()方法來啟動該線程。

        public class FirstThreadTest extends Thread {
            int i = 0;
            // 重寫run方法,run方法的方法體就是現場執行體
            public void run() {
                for (; i < 5; i++) {
                    System.out.println(getName() + "  " + i);
                }
            }
            public static void main(String[] args) {
                for (int i = 0; i < 3; i++) {
                    System.out.println(Thread.currentThread().getName() + "  : " + i);
                    if (i == 2) {
                        new FirstThreadTest().start();
                        new FirstThreadTest().start();
                    }
                }
            }
        }

        上述代碼中Thread.currentThread()方法返回當前正在執行的線程對象。GetName()方法返回調用該方法的線程的名字。

        1.2 通過Runnable接口創建線程類

        • 定義runnable接口的實現類,并重寫該接口的run()方法,該run()方法的方法體同樣是該線程的線程執行體。

        • 創建 Runnable實現類的實例,并以此實例作為Thread的target來創建Thread對象,該Thread對象才是真正的線程對象。

        • 調用線程對象的start()方法來啟動該線程。


        public class RunnableThreadTest implements Runnable {
            private int i;
            public void run() {
                for (i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + " " + i);
                }
            }
            public static void main(String[] args) {
                for (int i = 0; i < 3; i++) {
                    System.out.println(Thread.currentThread().getName() + " " + i);
                    if (i == 2) {
                        RunnableThreadTest rtt = new RunnableThreadTest();
                        new Thread(rtt, "新線程1").start();
                        new Thread(rtt, "新線程2").start();
                    }
                }
            }
        }

        線程的執行流程很簡單,當執行代碼start()時,就會執行對象中重寫的void run();方法,該方法執行完成后,線程就消亡了。

        使用Lambda表達式
        public class RunnableThreadTest {
            // 目的是為了代碼的重用【靜態方法】
            public static void threadRunCode_Static() {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + " " + i);
                }
            }
            // 目的是為了代碼的重用【非靜態方法】
            public void threadRunCode() {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + " " + i);
                }
            }
            @Test
            public void testStatic() {
                // 重用靜態方法中的代碼【使用方法引用】
                for (int i = 0; i < 3; i++) {
                    System.out.println(Thread.currentThread().getName() + " " + i);
                    if (i == 2) {
                        new Thread(RunnableThreadTest::threadRunCode_Static, "線程1").start();
                        ;
                        new Thread(RunnableThreadTest::threadRunCode_Static, "線程2").start();
                        ;
                    }
                }
            }
            @Test
            public void testNoStatic() {
                // 重用非靜態方法中的代碼【使用方法引用】
                RunnableThreadTest temp = new RunnableThreadTest();
                for (int i = 0; i < 3; i++) {
                    System.out.println(Thread.currentThread().getName() + " " + i);
                    if (i == 2) {
                        new Thread(temp::threadRunCode, "線程1").start();
                        new Thread(temp::threadRunCode, "線程2").start();
                    }
                }
            }
            @Test
            public void testLambda() {
                // 重用靜態方法中的代碼【使用方法引用】
                for (int i = 0; i < 3; i++) {
                    System.out.println(Thread.currentThread().getName() + " " + i);
                    if (i == 2) {
                        new Thread(() -> {
                            for (int b = 0; b < 5; b++) {
                                System.out.println(Thread.currentThread().getName() + " " + b);
                            }
                        },"線程1").start();
                        new Thread(() -> {
                            for (int b = 0; b < 5; b++) {
                                System.out.println(Thread.currentThread().getName() + " " + b);
                            }
                        },"線程2").start();
                    }
                }
            }
        }

        1.3 通過Callable和Future創建線程

        public interface Callable{
          V call() throws Exception;
        }
        • 創建Callable接口的實現類,并實現call()方法,該call()方法將作為線程執行體,并且有返回值。

        • 創建Callable實現類的實例,使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了該Callable對象的call()方法的返回值。(FutureTask是一個包裝器,它通過接受Callable來創建,它同時實現了Future和Runnable接口。)

        • 使用FutureTask對象作為Thread對象的target創建并啟動新線程。

        • 調用FutureTask對象的get()方法來獲得子線程執行結束后的返回值

        public class CallableThreadTest implements Callable<Integer> {
            @Override
            public Integer call() throws Exception {
                int i = 0;
                for (; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + " " + i);
                }
                return i;
            }
            public static void main(String[] args) {
                CallableThreadTest ctt = new CallableThreadTest();
                FutureTask<Integer> ft = new FutureTask<>(ctt);
                for (int i = 0; i < 3; i++) {
                    System.out.println(Thread.currentThread().getName() + " 的循環變量i的值" + i);
                    if (i == 2) {
                        new Thread(ft, "有返回值的線程").start();
                    }
                }
                try {
                    System.out.println("子線程的返回值:" + ft.get());
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }
        使用Lambda表達式
        public class CallableThreadTest {
            public static void main(String[] args) {
                FutureTask<Integer> ft = new FutureTask<>(() -> {
                    int i = 0;
                    for (; i < 5; i++) {
                        System.out.println(Thread.currentThread().getName() + " " + i);
                    }
                    return i;
                });
                for (int i = 0; i < 3; i++) {
                    System.out.println(Thread.currentThread().getName() + " 的循環變量i的值" + i);
                    if (i == 2) {
                        new Thread(ft, "有返回值的線程").start();
                    }
                }
                try {
                    System.out.println("子線程的返回值:" + ft.get());
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }

        二、創建線程的三種方式的對比

        2.1 實現Runnable、Callable接口的方式創建多線程

        優勢:

        • 線程類只是實現了Runnable接口或Callable接口,還可以繼承其他類。

        • 在這種方式下,多個線程可以共享同一個target對象,所以非常適合多個相同線程來處理同一份資源的情況,從而可以將CPU、代碼和數據分開,形成清晰的模型,較好地體現了面向對象的思想。

        劣勢:

        • 編程稍微復雜,如果要訪問當前線程,則必須使用Thread.currentThread()方法。

        2.2 繼承Thread類的方式創建多線程

        優勢:

        • 編寫簡單,如果需要訪問當前線程,則無需使用Thread.currentThread()方法,直接使用this即可獲得當前線程。

        劣勢:

        • 線程類已經繼承了Thread類,所以不能再繼承其他父類。

        2.3 Runnable和Callable的區別

        • Callable規定(重寫)的方法是call(),Runnable規定(重寫)的方法是run()。

        • Callable的任務執行后可返回值,而Runnable的任務是不能返回值的。

        • call方法可以拋出異常,run方法不可以。

        • 運行Callable任務可以拿到一個Future對象,表示異步計算的結果。它提供了檢查計算是否完成的方法,以等待計算的完成,并檢索計算的結果。通過Future對象可以了解任務執行情況,可取消任務的執行,還可獲取執行結果。

        “Java怎么創建線程及配合使用Lambda方式”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

        向AI問一下細節

        免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

        AI

        交城县| 西丰县| 洛川县| 安顺市| 宣汉县| 高州市| 寿宁县| 孟村| 康定县| 蒙城县| 剑阁县| 常熟市| 锡林浩特市| 商河县| 天祝| 安达市| 荃湾区| 大庆市| 大冶市| 渭南市| 天津市| 长宁区| 嘉兴市| 南通市| 牙克石市| 繁昌县| 运城市| 宝应县| 区。| 达孜县| 贵港市| 柳江县| 辉县市| 准格尔旗| 读书| 遂平县| 宁城县| 衡阳县| 道真| 长泰县| 峨边|