欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中實(shí)現(xiàn)多線程的幾種方式總結(jié)

 更新時(shí)間:2025年01月08日 14:41:39   作者:夜夜流光相皎潔_小寧  
文章介紹了三種創(chuàng)建線程的方式:繼承Thread類、實(shí)現(xiàn)Runnable接口和實(shí)現(xiàn)Callable接口,并比較了它們之間的區(qū)別和優(yōu)缺點(diǎn)

Java實(shí)現(xiàn)多線程的幾種方式

1)繼承Thread類

實(shí)現(xiàn)的步驟:

  • 1)創(chuàng)建Thread類的子類
  • 2)重寫run方法
  • 3)創(chuàng)建線程對象
  • 4)啟動線程

代碼示例:

package com.bobo.thread;

public class ThreadDemo02 {

    /**
     * 線程的第一種實(shí)現(xiàn)方式
     *     通過創(chuàng)建Thread類的子類來實(shí)現(xiàn)
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("main方法執(zhí)行了1...");
        // Java中的線程 本質(zhì)上就是一個(gè)Thread對象
        Thread t1 = new ThreadTest01();
        // 啟動一個(gè)新的線程
        t1.start();
        for(int i = 0 ; i< 100 ; i++){
            System.out.println("main方法的循環(huán)..."+i);
        }
        System.out.println("main方法執(zhí)行結(jié)束了3...");
    }
}
/**
 * 第一個(gè)自定義的線程類
 *    繼承Thread父類
 *    重寫run方法
 */
class ThreadTest01 extends Thread{

    @Override
    public void run() {
        System.out.println("我們的第一個(gè)線程執(zhí)行了2....");
        for(int i = 0 ; i < 10 ; i ++){
            System.out.println("子線程:"+i);
        }
    }
}

注意點(diǎn):

1)啟動線程是使用start方法而不是run方法

2)線程不能啟動多次,如果要創(chuàng)建多個(gè)線程,那么就需要創(chuàng)建多個(gè)Thread對象

2)實(shí)現(xiàn)Runnable接口

在第一種實(shí)現(xiàn)方式中,我們是將線程的創(chuàng)建和線程執(zhí)行的業(yè)務(wù)都封裝在了Thread對象中,我們可以通過Runable接口來實(shí)現(xiàn)線程程序代碼和數(shù)據(jù)有效的分離。

實(shí)現(xiàn)的步驟:

  • 1)創(chuàng)建Runable的實(shí)現(xiàn)類
  • 2)重寫run方法
  • 3)創(chuàng)建Runable實(shí)例對象(通過實(shí)現(xiàn)類來實(shí)現(xiàn))
  • 4)創(chuàng)建Thread對象,并把第三步創(chuàng)建的Runable實(shí)例作為Thread構(gòu)造方法的參數(shù)
  • 5)啟動線程

代碼示例:

package com.bobo.runable;

public class RunableDemo01 {

    /**
     * 線程的第二種方式
     *     本質(zhì)是創(chuàng)建Thread對象的時(shí)候傳遞了一個(gè)Runable接口實(shí)現(xiàn)
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("main執(zhí)行了...");
        // 創(chuàng)建一個(gè)新的線程  Thread對象
        Runnable r1 = new RunableTest();
        Thread t1 = new Thread(r1);
        // 啟動線程
        t1.start();
        System.out.println("main結(jié)束了...");
    }
}

/**
 * 線程的第二種創(chuàng)建方式
 *   創(chuàng)建一個(gè)Runable接口的實(shí)現(xiàn)類
 */
class RunableTest implements Runnable{

    @Override
    public void run() {
        System.out.println("子線程執(zhí)行了...");
    }
}

實(shí)現(xiàn)Runable接口的好處:

1)可以避免Java單繼承帶來的局限性

2)適合多個(gè)相同的程序代碼處理同一個(gè)資源的情況,把線程同程序的代碼和數(shù)據(jù)有效的分離,較好的體現(xiàn)了面向?qū)ο蟮脑O(shè)計(jì)思想

3)實(shí)現(xiàn)Callable接口(JDK1.5>=)

前面我們介紹的兩種創(chuàng)建線程的方式都是重寫run方法,而且run方法是沒有返回結(jié)果的,也就是main方法是不知道開啟的線程什么時(shí)候開始執(zhí)行,什么時(shí)候結(jié)束執(zhí)行,也獲取不到對應(yīng)的返回結(jié)果。而且run方法也不能把可能產(chǎn)生的異常拋出。

在JDK1.5之后推出了通過實(shí)現(xiàn)Callable接口的方式來創(chuàng)建新的線程,這種方式可以獲取對應(yīng)的返回結(jié)果。

代碼示例:

package com.bobo.callable;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

public class CallableDemo01 {

    /**
     * 創(chuàng)建線程的第三種實(shí)現(xiàn)方式:
     *    Callable方式
     */
    public static void main(String[] args) throws  Exception {
        // 創(chuàng)建一個(gè)Callable實(shí)例
        Callable<Integer> callable = new MyCallable();
        FutureTask<Integer> futureTask = new FutureTask<>(callable);
        // 獲取一個(gè)線程 肯定是要先創(chuàng)建一個(gè)Thread對象  futureTask本質(zhì)上是Runable接口的實(shí)現(xiàn)
        Thread t1 = new Thread(futureTask);
        System.out.println("main方法start....");
        t1.start(); // 本質(zhì)還是執(zhí)行的 Runable中的run方法,只是 run方法調(diào)用了call方法罷了
        // 獲取返回的結(jié)果
        System.out.println(futureTask.get()); // 獲取開啟的線程執(zhí)行完成后返回的結(jié)果
        System.out.println("main方法end ....");

    }
}

/**
 * 創(chuàng)建Callable的實(shí)現(xiàn)類
 *    我們需要指定Callable的泛型,這個(gè)泛型是返回結(jié)果的類型
 */
class MyCallable implements Callable<Integer>{

    /**
     * 線程自動后會執(zhí)行的方法
     * @return
     * @throws Exception
     */
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for(int i = 1 ; i <= 100 ; i ++){
            sum += i;
        }
        return sum;
    }
}

實(shí)現(xiàn)Runnable接口和實(shí)現(xiàn)Callable接口的區(qū)別:

  • 1)Runnable是自從java1.1就有了,而Callable是1.5之后才加上去的
  • 2)Callable規(guī)定的方法是call(),Runnable規(guī)定的方法是run()
  • 3)Callable的任務(wù)執(zhí)行后可返回值,而Runnable的任務(wù)是不能返回值(是void)
  • 4)call方法可以拋出異常,run方法不可以
  • 5)運(yùn)行Callable任務(wù)可以拿到一個(gè)Future對象,表示異步計(jì)算的結(jié)果。它提供了檢查計(jì)算是否完成的方法,以等待計(jì)算的完成,并檢索計(jì)算的結(jié)果。通過Future對象可以了解任務(wù)執(zhí)行情況,可取消任務(wù)的執(zhí)行,還可獲取執(zhí)行結(jié)果。

4)線程池方式創(chuàng)建

加入線程池運(yùn)行,Runnable使用ExecutorService的execute方法,Callable使用submit方法。

其實(shí)Callable接口底層的實(shí)現(xiàn)就是對Runable接口實(shí)現(xiàn)的封裝,線程啟動執(zhí)行的也是Runable接口實(shí)現(xiàn)中的run方法,只是在run方法中有調(diào)用call方法罷了

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java嵌套for循環(huán)的幾種常見優(yōu)化方案

    Java嵌套for循環(huán)的幾種常見優(yōu)化方案

    這篇文章主要給大家介紹了關(guān)于Java嵌套for循環(huán)的幾種常見優(yōu)化,在Java中優(yōu)化嵌套for循環(huán)可以通過以下幾種方式來提高性能和效率,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • Java實(shí)現(xiàn)中國象棋的示例代碼

    Java實(shí)現(xiàn)中國象棋的示例代碼

    中國象棋是起源于中國的一種棋,屬于二人對抗性游戲的一種,在中國有著悠久的歷史。由于用具簡單,趣味性強(qiáng),成為流行極為廣泛的棋藝活動。本文將利用Java實(shí)現(xiàn)這一經(jīng)典游戲,需要的可以參考一下
    2022-02-02
  • Java中的Set接口實(shí)現(xiàn)類HashSet和LinkedHashSet詳解

    Java中的Set接口實(shí)現(xiàn)類HashSet和LinkedHashSet詳解

    這篇文章主要介紹了Java中的Set接口實(shí)現(xiàn)類HashSet和LinkedHashSet詳解,Set接口和java.util.List接口一樣,同樣繼承自Collection接口,它與Collection接口中的方法基本一致,并沒有對Collection接口進(jìn)行功能上的擴(kuò)充,只是比Collection接口更加嚴(yán)格了,需要的朋友可以參考下
    2024-01-01
  • Java序列化機(jī)制詳解

    Java序列化機(jī)制詳解

    Java 序列化機(jī)制是一種將對象轉(zhuǎn)換為字節(jié)流的過程,以便在網(wǎng)絡(luò)上傳輸或保存到文件中,并能在需要時(shí)將字節(jié)流還原為對象,這一機(jī)制通過實(shí)現(xiàn) java.io.Serializable 接口來實(shí)現(xiàn),同時(shí)涉及到一些關(guān)鍵概念和注意事項(xiàng),需要的朋友可以參考下
    2023-12-12
  • eclipse/IDEA配置javafx項(xiàng)目步驟(圖文教程)

    eclipse/IDEA配置javafx項(xiàng)目步驟(圖文教程)

    這篇文章主要介紹了eclipse/IDEA配置javafx項(xiàng)目步驟(圖文教程),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • 詳解Mybatis中javaType和ofType的區(qū)別

    詳解Mybatis中javaType和ofType的區(qū)別

    本文主要介紹了詳解Mybatis中javaType和ofType的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Eclipse中安裝反編譯工具Fernflower的方法(Enhanced Class Decompiler)

    Eclipse中安裝反編譯工具Fernflower的方法(Enhanced Class Decompiler)

    這篇文章主要介紹了Eclipse中安裝反編譯工具Fernflower的方法(Enhanced Class Decompiler),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • MyBatis中RowBounds實(shí)現(xiàn)內(nèi)存分頁

    MyBatis中RowBounds實(shí)現(xiàn)內(nèi)存分頁

    RowBounds是MyBatis提供的一種內(nèi)存分頁方式,適用于小數(shù)據(jù)量的分頁場景,本文就來詳細(xì)的介紹一下,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-12-12
  • Java 泛型總結(jié)(一):基本用法與類型擦除

    Java 泛型總結(jié)(一):基本用法與類型擦除

    本文主要介紹了Java泛型的使用以及類型擦除相關(guān)的問題。具有很好的參考價(jià)值。下面跟著小編一起來看下吧
    2017-03-03
  • Java延遲隊(duì)列原理與用法實(shí)例詳解

    Java延遲隊(duì)列原理與用法實(shí)例詳解

    這篇文章主要介紹了Java延遲隊(duì)列原理與用法,結(jié)合實(shí)例形式詳細(xì)分析了延遲隊(duì)列的概念、原理、功能及具體使用方法,需要的朋友可以參考下
    2018-09-09

最新評論