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

Java?Runnable和Thread實(shí)現(xiàn)多線程哪個(gè)更好你知道嗎

 更新時(shí)間:2022年03月02日 16:59:05   作者:小小茶花女  
這篇文章主要為大家詳細(xì)介紹了Java?Runnable和Thread實(shí)現(xiàn)多線程哪個(gè)更好,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助<BR>

實(shí)現(xiàn)Runnable 接口比繼承Thread 類的方式更好:

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

(2)可以實(shí)現(xiàn)業(yè)務(wù)執(zhí)行邏輯和數(shù)據(jù)資源的分離;

(3)可以與線程池配合使用,從而管理線程的生命周期;

1. 避免由于Java單繼承帶來的局限性

如果異步邏輯所在類已經(jīng)繼承了一個(gè)基類,就沒有辦法再繼承Thread類。比如,當(dāng)一個(gè)Dog類繼承了Pet類,再要繼承Thread類就不行了。所以在已經(jīng)存在繼承關(guān)系的情況下,只能使用實(shí)現(xiàn)Runnable接口的方式。

public class ThreadTask extends Thread {
    // 線程的執(zhí)行體
    @Override
    public void run() {
        System.out.println("線程執(zhí)行的任務(wù)");
    }
}
public class RunnableTask implements Runnable {
    // 線程的執(zhí)行體
    @Override
    public void run() {
        System.out.println("線程執(zhí)行的任務(wù)");
    }
}

2. 可以實(shí)現(xiàn)業(yè)務(wù)執(zhí)行邏輯和數(shù)據(jù)資源的分離

邏輯和數(shù)據(jù)更好分離。通過實(shí)現(xiàn)Runnable接口的方法創(chuàng)建多線程更加適合同一個(gè)資源被多段業(yè)務(wù)邏輯并行處理的場(chǎng)景。在同一個(gè)資源被多個(gè)線程邏輯異步、并行處理的場(chǎng)景中,通過實(shí)現(xiàn)Runnable接口的方式設(shè)計(jì)多個(gè)target執(zhí)行目標(biāo)類可以更加方便、清晰地將執(zhí)行邏輯和數(shù)據(jù)存儲(chǔ)分離,更好地體現(xiàn)了面向?qū)ο蟮脑O(shè)計(jì)思想。

注意:并不是繼承Thread類不能實(shí)現(xiàn)資源共享,而是沒有實(shí)現(xiàn)Runnable接口更方便,更清晰,他們兩的主要區(qū)別就是類和接口的區(qū)別,但是我們一般多用Runnable。

(1) 通過繼承Thread類的方式實(shí)現(xiàn)多線程,數(shù)據(jù)資源和業(yè)務(wù)執(zhí)行邏輯是耦合在一起的, 多個(gè)線程并發(fā)地完成各自的任務(wù),訪問各自的數(shù)據(jù)資源,而不是共享一份數(shù)據(jù)資源:

public class ThreadDemo extends Thread {
    // 數(shù)據(jù)資源
    private int ticket = 3;
    // 業(yè)務(wù)執(zhí)行邏輯
    @Override
    public void run() {
        for(int i=0;i<3;i++){
            if(ticket>0){
                System.out.println(Thread.currentThread().getName()+" 賣票--->"+ ticket--);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println(Thread.currentThread().getName()+" 線程運(yùn)行結(jié)束");
    }
    public static void main(String[] args) throws InterruptedException {
        // 創(chuàng)建2個(gè)線程,分別去執(zhí)行線程體中的業(yè)務(wù)邏輯
        Thread thread1 = new ThreadDemo();
        thread1.start();
        Thread thread2 = new ThreadDemo();
        thread2.start();
        Thread.sleep(1000);
        System.out.println("main線程運(yùn)行結(jié)束");
    }
}

多個(gè)線程并發(fā)地完成各自的任務(wù),訪問各自的數(shù)據(jù)資源:

Thread-0 賣票--->3
Thread-1 賣票--->3
main線程運(yùn)行結(jié)束
Thread-0 賣票--->2
Thread-1 賣票--->2
Thread-1 賣票--->1
Thread-0 賣票--->1
Thread-0 線程運(yùn)行結(jié)束
Thread-1 線程運(yùn)行結(jié)束

(2) 通過繼承Thread類可以實(shí)現(xiàn)資源共享:

public class ThreadTask {
    private int ticket = 3;
    public synchronized void saleTicket(){
        for(int i=0;i<3;i++){
            if(ticket>0){
                System.out.println(Thread.currentThread().getName()+" 賣票--->"+ticket--);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println(Thread.currentThread().getName()+" 線程運(yùn)行結(jié)束");
    }
}
public class ThreadA extends Thread {
    ThreadTask threadTask ;
    public ThreadA(ThreadTask threadTask){
        super();
        this.threadTask = threadTask;
    }
    @Override
    public void run() {
        threadTask.saleTicket();
    }
}
public class ThreadB extends Thread {
    ThreadTask threadTask ;
    public ThreadB(ThreadTask threadTask){
        super();
        this.threadTask = threadTask;
    }
    @Override
    public void run() {
        threadTask.saleTicket();
    }
}
public class Main {
    public static void main(String[] args) throws InterruptedException {
        ThreadTask threadTask = new ThreadTask();
        ThreadA t1 = new ThreadA(threadTask);
        ThreadB t2 = new ThreadB(threadTask);
        t1.start();
        t2.start();
    }
}

執(zhí)行結(jié)果:

Thread-0 賣票--->3
Thread-1 賣票--->2
Thread-1 賣票--->1
Thread-0 線程運(yùn)行結(jié)束
Thread-1 線程運(yùn)行結(jié)束

(3) 通過實(shí)現(xiàn)Runnable接口實(shí)現(xiàn)多線程,能更好地做到多個(gè)線程并發(fā)地完成同一個(gè)任務(wù),訪問同一份數(shù)據(jù)資源。多個(gè)線程的代碼邏輯可以方便地訪問和處理同一個(gè)共享數(shù)據(jù)資源 ,這樣可以將線程邏輯和業(yè)務(wù)數(shù)據(jù)進(jìn)行有效的分離,更好地體現(xiàn)了面向?qū)ο蟮脑O(shè)計(jì)思想。

public class RunnableDemo{
    public static class RunnableTask  implements Runnable{
        // 數(shù)據(jù)資源
        private int ticket = 3;
        // 線程執(zhí)行體
        @Override
        public synchronized void run() {
            for(int i=0;i<3;i++){
                if(ticket>0){
                    System.out.println(Thread.currentThread().getName()+" 賣票--->"+ticket--);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            System.out.println(Thread.currentThread().getName()+" 線程運(yùn)行結(jié)束");
        }
    }
    public static void main(String[] args) {
        // 將這一個(gè)target作為參數(shù)傳給兩個(gè)線程,那么這兩個(gè)線程執(zhí)行的都是這個(gè)target的run()方法
        Runnable target = new RunnableTask();
        // 創(chuàng)建兩個(gè)線程執(zhí)行target的線程體
        Thread thread1 = new Thread(target,"thread1");
        thread1.start();
        Thread thread2 = new Thread(target,"thread2");
        thread2.start();
        System.out.println("main線程運(yùn)行結(jié)束");
    }
}

多個(gè)線程并發(fā)地完成同一個(gè)任務(wù),訪問同一份數(shù)據(jù)資源:

main線程運(yùn)行結(jié)束
thread1 賣票--->3
thread1 賣票--->2
thread1 賣票--->1
thread1 線程運(yùn)行結(jié)束
thread2 線程運(yùn)行結(jié)束

3. 可以與線程池配合使用,從而管理線程的生命周期

實(shí)現(xiàn)Runnable接口來實(shí)現(xiàn)線程,執(zhí)行目標(biāo)類,更容易和線程池配合使用,異步執(zhí)行任務(wù)在大多數(shù)情況下是通過線程池去提交的,而很少通過創(chuàng)建一個(gè)新的線程去提交,所以更多的做法是,通過實(shí)現(xiàn)Runnable接口創(chuàng)建異步執(zhí)行任務(wù),而不是繼承Thread去創(chuàng)建異步執(zhí)行任務(wù)。

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容! 

相關(guān)文章

  • Maven打包跳過測(cè)試的實(shí)現(xiàn)方法

    Maven打包跳過測(cè)試的實(shí)現(xiàn)方法

    使用Maven打包的時(shí)候,可能會(huì)因?yàn)閱卧獪y(cè)試打包失敗,這時(shí)候就需要跳過單元測(cè)試。本文就介紹了Maven打包跳過測(cè)試的實(shí)現(xiàn)方法,感興趣的可以了解一下
    2021-06-06
  • 使用springMVC所需要的pom配置

    使用springMVC所需要的pom配置

    這篇文章主要介紹了使用springMVC所需要的pom配置,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 一文詳解SpringMVC中的@RequestMapping注解

    一文詳解SpringMVC中的@RequestMapping注解

    @RequestMapping是一個(gè)用于映射HTTP請(qǐng)求到處理方法的注解,在Spring框架中使用,它可以用于控制器類和處理方法上,用來指定處理不同URL路徑的請(qǐng)求,并定義請(qǐng)求的方法等,本文小編將給大家詳細(xì)的介紹一下SpringMVC中的@RequestMapping注解,需要的朋友可以參考下
    2023-08-08
  • java學(xué)習(xí)DongTai被動(dòng)型IAST工具部署過程

    java學(xué)習(xí)DongTai被動(dòng)型IAST工具部署過程

    被動(dòng)型IAST被認(rèn)為是DevSecOps測(cè)試階段實(shí)現(xiàn)自動(dòng)化安全測(cè)試的最佳工具,而就在前幾天,洞態(tài)IAST正式開源了,這對(duì)于甲方構(gòu)建安全工具鏈來說,絕對(duì)是一個(gè)大利好
    2021-10-10
  • JAVA開發(fā)環(huán)境Vs?code配置步驟詳解

    JAVA開發(fā)環(huán)境Vs?code配置步驟詳解

    這篇文章主要為大家介紹了JAVA開發(fā)環(huán)境Vs?code配置步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • SpringCloud邁向云原生的步驟

    SpringCloud邁向云原生的步驟

    這篇文章主要介紹了SpringCloud怎么邁向云原生,通過本文我們來梳理一下Spring?Cloud的前世今生,以及未來云原生發(fā)展的趨勢(shì),可以給這些RPC框架的演進(jìn)帶來一些啟發(fā),感興趣的朋友跟隨小編一起看看吧
    2022-10-10
  • Spring Boot 2結(jié)合Spring security + JWT實(shí)現(xiàn)微信小程序登錄

    Spring Boot 2結(jié)合Spring security + JWT實(shí)現(xiàn)微信小程序登錄

    這篇文章主要介紹了Spring Boot 2結(jié)合Spring security + JWT實(shí)現(xiàn)微信小程序登錄,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • SpringBoot之Banner的使用示例

    SpringBoot之Banner的使用示例

    本篇文章主要介紹了SpringBoot之Banner的使用示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • Java線程關(guān)閉的3種方法

    Java線程關(guān)閉的3種方法

    這篇文章介紹了Java線程關(guān)閉的3種方法,有需要的朋友可以參考一下
    2013-10-10
  • 深入解析Java的Struts框架中的控制器DispatchAction

    深入解析Java的Struts框架中的控制器DispatchAction

    這篇文章主要介紹了深入解析Java的Struts框架中的控制器DispatchAction,Struts是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下
    2015-12-12

最新評(píng)論