簡(jiǎn)介
創(chuàng)建線程,是多線程編程中最基本的操作,彤哥總結(jié)了一下,大概有8種創(chuàng)建線程的方式,你知道嗎?
繼承Thread類并重寫run()方法
繼承Thread類并重寫run()方法,這種方式的弊端是一個(gè)類只能繼承一個(gè)父類,如果這個(gè)類本身已經(jīng)繼承了其它類,就不能使用這種方式了。
實(shí)現(xiàn)Runnable接口
實(shí)現(xiàn)Runnable接口,這種方式的好處是一個(gè)類可以實(shí)現(xiàn)多個(gè)接口,不影響其繼承體系。
匿名內(nèi)部類
使用匿名類的方式,一是重寫Thread的run()方法,二是傳入Runnable的匿名類,三是使用lambda方式,現(xiàn)在一般使用第三種(java8+),簡(jiǎn)單快捷。
實(shí)現(xiàn)Callabe接口
實(shí)現(xiàn)Callabe接口,可以獲取線程執(zhí)行的結(jié)果,F(xiàn)utureTask實(shí)際上實(shí)現(xiàn)了Runnable接口。
定時(shí)器(java.util.Timer)
使用定時(shí)器java.util.Timer可以快速地實(shí)現(xiàn)定時(shí)任務(wù),TimerTask實(shí)際上實(shí)現(xiàn)了Runnable接口。
線程池
使用線程池的方式,可以復(fù)用線程,節(jié)約系統(tǒng)資源。
并行計(jì)算(Java8+)
使用并行計(jì)算的方式,可以提高程序運(yùn)行的效率,多線程并行執(zhí)行。
Spring異步方法
首先,springboot啟動(dòng)類加上@EnableAsync注解(@EnableAsync是spring支持的,這里方便舉例使用springboot)。
其次,方法加上@Async注解。
然后,測(cè)試用例直接跟使用一般的Service方法一模一樣。
運(yùn)行結(jié)果如下:
可以看到每次執(zhí)行方法時(shí)使用的線程都不一樣。
使用Spring異步方法的方式,可以說(shuō)是相當(dāng)?shù)胤奖?,適用于前后邏輯不相關(guān)聯(lián)的適合用異步調(diào)用的一些方法,比如發(fā)送短信的功能。
總結(jié)
(1)繼承Thread類并重寫run()方法;
(2)實(shí)現(xiàn)Runnable接口;
(3)匿名內(nèi)部類;
(4)實(shí)現(xiàn)Callabe接口;
(5)定時(shí)器(java.util.Timer);
(6)線程池;
(7)并行計(jì)算(Java8+);
(8)Spring異步方法;
彩蛋
上面介紹了那么多創(chuàng)建線程的方式,其實(shí)本質(zhì)上就兩種,一種是繼承Thread類并重寫其run()方法,一種是實(shí)現(xiàn)Runnable接口的run()方法,那么它們之間到底有什么聯(lián)系呢?
請(qǐng)看下面的例子,同時(shí)繼承Thread并實(shí)現(xiàn)Runnable接口,應(yīng)該輸出什么呢?
說(shuō)到這里,我們有必要看一下Thread類的源碼:
看到這里是不是豁然開朗呢?既然上面的例子同時(shí)繼承Thread并實(shí)現(xiàn)了Runnable接口,根據(jù)源碼,實(shí)際上相當(dāng)于重寫了Thread的run()方法,在Thread的run()方法時(shí)實(shí)際上跟target都沒有關(guān)系了。
所以,上面的例子輸出結(jié)果為Thread: Thread-0,只輸出重寫Thread的run()方法中的內(nèi)容。
【責(zé)任編輯:龐桂玉 TEL:(010)68476606】