溫馨提示×

溫馨提示×

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

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

Java并發(fā)編程如何創(chuàng)建并運行線程

發(fā)布時間:2022-03-18 16:08:23 來源:億速云 閱讀:175 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“Java并發(fā)編程如何創(chuàng)建并運行線程”,在日常操作中,相信很多人在Java并發(fā)編程如何創(chuàng)建并運行線程問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java并發(fā)編程如何創(chuàng)建并運行線程”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

    一、創(chuàng)建并運行線程的五種方法

    第一種:繼承Thread類

    這種方式是最基礎(chǔ)的一種方式,學(xué)過java的朋友都知道,不做贅述。需要注意的是:覆蓋實現(xiàn)使用的是run方法,運行線程是start方法。

    public class FirstWay extends Thread  {
        @Override
        public void run() {
            System.out.println("第一種實現(xiàn)線程的方式:繼承Thread類");
        }
        //模擬測試
        public static void main(String[] args) {
            new FirstWay().start();
        }
    }

    第二種:實現(xiàn)Runnable接口

    第二種實現(xiàn)方式仍然很基礎(chǔ),繼承Runnable接口,重寫run方法實現(xiàn)線程運行邏輯。需要注意的:運行線程需要套一層new Thread 。

    public class SecondWay implements Runnable{
        @Override
        public void run() {
            System.out.println("第二種實現(xiàn)線程的方式:實現(xiàn)Runnable接口");
        }
        //模擬測試
        public static void main(String[] args) {
            new Thread(new SecondWay()).start();
        }
    }

    第三種:實現(xiàn)Callable接口

    第三種方式是實現(xiàn)Callable接口,Callable接口與Runable接口都能實現(xiàn)線程。

    public class ThirdWay implements Callable<String> {
        @Override
        public String call() throws Exception {
            System.out.println("第三種實現(xiàn)線程的方式:實現(xiàn)Callable接口");
            return "Callable接口帶返回值,可以拋出異常";
        }
    
        //模擬測試
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            FutureTask<String> futureTask = new FutureTask<>(new ThirdWay());
            new Thread(futureTask).start();
            //阻塞方法,獲取call方法返回值
            System.out.println(futureTask.get());  //打?。篊allable接口帶返回值,可以拋出異常
        }
    }

    區(qū)別如下:

    • Callable接口實現(xiàn)線程方法是call, Runable接口實現(xiàn)線程方法是run

    • Callable有返回值, Runable接口不能有返回值

    • Callable接口方法call返回值可以設(shè)置泛型,如下例子中使用String數(shù)據(jù)類型

    • Callable接口方法call方法可以拋出異常,Runable接口run方法不可以拋出異常

    • Callable接口方法通過new Thread(futureTask).start()運行,F(xiàn)utureTask的get方法可以獲取Callable接口方法call方法的返回值

    • 如果Callable接口方法call方法異常,在FutureTask的get方法調(diào)用時也會拋出同樣的異常

    第四種:線程池 + execute

    從JDK5版本開始,java默認(rèn)提供了線程池的支持,用線程池的方式運行線程可以避免線程的無限擴(kuò)張導(dǎo)致應(yīng)用宕機(jī),同時也節(jié)省了線程頻繁創(chuàng)建與銷毀的資源與時間成本。

    public class FourthWay implements Runnable{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() +
                    ":實現(xiàn)線程的方式Runnable接口,但運行方式不一樣,使用線程池");
        }
    
        public static void main(String[] args) {
            //創(chuàng)建一個固定大小的線程池
            ExecutorService threadPool = Executors.newFixedThreadPool(5);
            for(int i = 0;i < 10;i++){
                threadPool.execute(new FourthWay());
            }
        }
    }

    線程池ExecutorService使用execute方法運行Runnable接口run方法的線程實現(xiàn),execute方法與run方法的共同特點是沒有返回值。

    pool-1-thread-5:實現(xiàn)線程的方式Runnable接口,但運行方式不一樣,使用線程池
    pool-1-thread-2:實現(xiàn)線程的方式Runnable接口,但運行方式不一樣,使用線程池
    pool-1-thread-4:實現(xiàn)線程的方式Runnable接口,但運行方式不一樣,使用線程池
    pool-1-thread-4:實現(xiàn)線程的方式Runnable接口,但運行方式不一樣,使用線程池
    pool-1-thread-4:實現(xiàn)線程的方式Runnable接口,但運行方式不一樣,使用線程池
    pool-1-thread-1:實現(xiàn)線程的方式Runnable接口,但運行方式不一樣,使用線程池
    pool-1-thread-4:實現(xiàn)線程的方式Runnable接口,但運行方式不一樣,使用線程池
    pool-1-thread-3:實現(xiàn)線程的方式Runnable接口,但運行方式不一樣,使用線程池
    pool-1-thread-2:實現(xiàn)線程的方式Runnable接口,但運行方式不一樣,使用線程池
    pool-1-thread-5:實現(xiàn)線程的方式Runnable接口,但運行方式不一樣,使用線程池

    從上面的結(jié)果中可以看出,線程池中包含五個線程。線程運行完成之后并不銷毀,而是還回到線程池,下一次執(zhí)行時從線程池中獲取線程資源再次運行。

    第五種:線程池 + submit

    下面的例子線程池ExecutorService使用submit方法運行Callable接口call方法的線程實現(xiàn),submit方法與call方法的共同特點是存在返回值。

    • Callable接口call方法的返回值可以由泛型定義

    • ExecutorService線程池submit方法的返回值是Future

    Future的get方法可以獲取call方法的返回值,同時如果call方法拋出異常,F(xiàn)uture的get方法也會拋出異常。

    public class FifthWay implements Callable<String> {
        @Override
        public String call() throws Exception {
            return Thread.currentThread().getName() + ":Callable接口帶返回值,可以拋出異常";
        }
    
        //模擬測試
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            //保存多線程執(zhí)行結(jié)果
            List<String> retList = new ArrayList<>();
            //創(chuàng)建一個固定大小的線程池
            ExecutorService threadPool = Executors.newFixedThreadPool(5);
            for(int i = 0;i < 10;i++){
                Future<String> future = threadPool.submit(new FifthWay());
                retList.add(future.get());
            }
            //java8 語法,打印retlist
            retList.forEach(System.out::println);
        }
    }

    上文代碼中有一個小小的語法糖,retList.forEach(System.out::println);是java8提供的方法引用

    pool-1-thread-1:Callable接口帶返回值,可以拋出異常
    pool-1-thread-2:Callable接口帶返回值,可以拋出異常
    pool-1-thread-3:Callable接口帶返回值,可以拋出異常
    pool-1-thread-4:Callable接口帶返回值,可以拋出異常
    pool-1-thread-5:Callable接口帶返回值,可以拋出異常
    pool-1-thread-1:Callable接口帶返回值,可以拋出異常
    pool-1-thread-2:Callable接口帶返回值,可以拋出異常
    pool-1-thread-3:Callable接口帶返回值,可以拋出異常
    pool-1-thread-4:Callable接口帶返回值,可以拋出異常
    pool-1-thread-5:Callable接口帶返回值,可以拋出異常

    到此,關(guān)于“Java并發(fā)編程如何創(chuàng)建并運行線程”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

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

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

    AI