溫馨提示×

溫馨提示×

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

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

Java中怎樣實(shí)現(xiàn)多線程

發(fā)布時(shí)間:2021-08-09 13:53:02 來源:億速云 閱讀:140 作者:Leah 欄目:大數(shù)據(jù)

本篇文章給大家分享的是有關(guān)Java中怎樣實(shí)現(xiàn)多線程,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

Java多線程實(shí)現(xiàn)有三種:

   三種方式分別通過代碼實(shí)例講解:

1、繼承Thread類

    繼承Thread并重寫run()方法,Thread類中的start方法會(huì)去調(diào)用系統(tǒng)的方法執(zhí)行相應(yīng)的線程。實(shí)際上Thread也是實(shí)現(xiàn)了Runable接口的,如圖:

Java中怎樣實(shí)現(xiàn)多線程代碼實(shí)例:

package com.hadoop.ljs.learning.thread;/** *功能描述  線程測試類 第一種方式  繼承自Thread類 * @author lujisen<ChinaUnicom Software JiNan> * @date  * @param   * @return  */public class MyThread extends  Thread {    public static int sum=0;    @Override    public void run() {        while (true){            //打印線程信息            System.out.println("線程名稱:"+Thread.currentThread().getName()+"當(dāng)前sum值:"+(sum++));            try {                sleep(5000);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    public static void  main(String[] args){        /*創(chuàng)建三個(gè)線程*/        MyThread thread1=new MyThread("線程1");        MyThread thread2=new MyThread("線程2");        MyThread thread3=new MyThread("線程3");
       thread1.start();        thread2.start();        thread3.start();    }     MyThread(String  threadName) {        Thread.currentThread().setName(threadName);    }}

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

    實(shí)現(xiàn)Runable接口,并重寫run()方法,啟動(dòng)線程必須要使用Thread類的start()方法,代碼實(shí)例:

package com.hadoop.ljs.learning.thread;import static java.lang.Thread.sleep;/*繼承Runnable接口*/public class MyThread2 implements  Runnable {    public static int sum=0;    @Override    public void run() {        while (true){            //打印線程信息            System.out.println("線程名稱:"+Thread.currentThread().getName()+"當(dāng)前sum值:"+(sum++));            try {                sleep(5000);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    public  static  void main(String[] args){        MyThread2 threadA=new MyThread2();        Thread thread1=new Thread(threadA);        thread1.setName("線程A");        thread1.start();        MyThread2 threadB=new MyThread2();        Thread thread2=new Thread(threadB);        thread2.setName("線程B");        thread2.start();        MyThread2 threadC=new MyThread2();        Thread thread3=new Thread(threadC);        thread3.setName("線程C");        thread3.start();    }}

3、實(shí)現(xiàn)Callable接口

    上面的兩個(gè)方式有兩個(gè)問題,第一個(gè)是無法拋出更多的異常,第二個(gè)是線程執(zhí)行完畢之后并無法獲得線程的返回值。那么下面的這種實(shí)現(xiàn)方式就可以完成我們的需求; 從Java5開始就提供了Callable接口,該接口是Runnable接口的增強(qiáng)版,Callable接口提供一個(gè)call()方法作為線程執(zhí)行體,call()方法可以有返回值,call()方法可以聲明拋出異常,但是這種方式比較復(fù)雜,大體步驟如下:

  • 1).創(chuàng)建一個(gè)類實(shí)現(xiàn)Callable接口,實(shí)現(xiàn)call方法。這個(gè)接口類似于Runnable接口,但比Runnable接口更加強(qiáng)大,增加了異常和返回值。

  • 2).創(chuàng)建一個(gè)FutureTask,指定Callable對象,做為線程任務(wù)。

  • 3).創(chuàng)建線程,指定線程任務(wù)。

代碼實(shí)例:

package com.hadoop.ljs.learning.thread;
import java.util.concurrent.Callable;import java.util.concurrent.FutureTask;/** * @author: Created By lujisen * @company ChinaUnicom Software JiNan * @date: 2020-02-19 19:29 * @version: v1.0 * @description: com.hadoop.ljs.learning.thread *//*創(chuàng)建一個(gè)類實(shí)現(xiàn)Callable接口*/public class MyThreadCallable1  implements Callable<Integer>{    // 實(shí)現(xiàn)call方法。這個(gè)接口類似于Runnable接口,但比Runnable接口更加強(qiáng)大,增加了異常和返回值    @Override    public Integer call() throws Exception {        System.out.println("實(shí)現(xiàn)call函數(shù)開始業(yè)務(wù)邏輯....");        Thread.sleep(5000);        /*這里有返回值*/        return 1;    }    public static void main(String[] args) throws Exception {        // 創(chuàng)建一個(gè)FutureTask,指定Callable對象,做為線程任務(wù)。        FutureTask<Integer> task = new FutureTask<>(new MyThreadCallable1());        // 啟動(dòng)線程        new Thread(task).start();        // 這里是在線程啟動(dòng)之后,結(jié)果返回之前,可干別的        System.out.println("線程啟動(dòng)之后,可自定義業(yè)務(wù)邏輯,因?yàn)樯厦婢€程call函數(shù)中睡眠了5秒....");        // 獲取線程結(jié)果        Integer result = task.get();        System.out.println("主線程中異步任務(wù)執(zhí)行的結(jié)果為:" + result);    }}


三種方式區(qū)別:

  1. 第一種方式繼承Thread就不能繼承其他類了,后面兩種可以;

  2. 使用后兩種方式可以多個(gè)線程共享一個(gè)target;,所以非常適合多個(gè)相同線程來處理同一份資源的情況,從而可以將CPU、代碼和數(shù)據(jù)分開,形成清晰的模型,較好地體現(xiàn)了面向?qū)ο蟮乃枷搿?/p>

  3. 獲取和設(shè)置線程名稱時(shí),第一種既可使用this.setName()和this.getName()分別設(shè)置和獲取當(dāng)前線程名稱也可使用Thread.currentThread().getName()和Thread.currentThread().setName(),而后兩種必須要使用Thread.currentThread().getName()。

  4. Callable規(guī)定(重寫)的方法是call(),Runnable規(guī)定(重寫)的方法是run();Callable的任務(wù)執(zhí)行后可返回值,而Runnable的任務(wù)是不能返回值的;call方法可以拋出異常,run方法不可以;

  5. 運(yùn)行Callable任務(wù)可以拿到一個(gè)Future對象,表示異步計(jì)算的結(jié)果。它提供了檢查計(jì)算是否完成的方法,以等待計(jì)算的完成,并檢索計(jì)算的結(jié)果。通過Future對象可以了解任務(wù)執(zhí)行情況,可取消任務(wù)的執(zhí)行,還可獲取執(zhí)行結(jié)果。

以上就是Java中怎樣實(shí)現(xiàn)多線程,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI