分享Java多線程實(shí)現(xiàn)的四種方式
以下四種方式:
- 1.繼承Thread類(lèi),重寫(xiě)run方法
- 2.實(shí)現(xiàn)Runnable接口,重寫(xiě)run方法,實(shí)現(xiàn)
Runnable接口的實(shí)現(xiàn)類(lèi)的實(shí)例對(duì)象作為T(mén)hread構(gòu)造函數(shù)的target - 3.通過(guò)Callable和FutureTask創(chuàng)建線程
- 4.通過(guò)線程池創(chuàng)建線程
后面兩種可以歸結(jié)成一類(lèi):有返回值,通過(guò)Callable接口,就要實(shí)現(xiàn)call方法,這個(gè)方法的返回值是Object,所以返回的結(jié)果可以放在Object對(duì)象中。
第一種:繼承Thread類(lèi),重寫(xiě)該類(lèi)的run()方法。
class MyThread extends Thread {
private int i = 0;
@Override
public void run() {
for (i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
public class ThreadDemo1 {
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
if (i == 30) {
// 創(chuàng)建一個(gè)新的線程 myThread1 此線程進(jìn)入新建狀態(tài)
Thread myThread1 = new MyThread();
// 創(chuàng)建一個(gè)新的線程 myThread2 此線程進(jìn)入新建狀態(tài)
Thread myThread2 = new MyThread();
// 調(diào)用start()方法使得線程進(jìn)入就緒狀態(tài)
myThread1.start();
// 調(diào)用start()方法使得線程進(jìn)入就緒狀態(tài)
myThread2.start();
}
}
}
}如上所示,繼承Thread類(lèi),通過(guò)重寫(xiě)run()方法定義了一個(gè)新的線程類(lèi)MyThread,其中run()方法的方法體代表了線程需要完成的任務(wù),稱(chēng)之為線程執(zhí)行體。當(dāng)創(chuàng)建此線程類(lèi)對(duì)象時(shí)一個(gè)新的線程得以創(chuàng)建,并進(jìn)入到線程新建狀態(tài)。通過(guò)調(diào)用線程對(duì)象引用的start()方法,使得該線程進(jìn)入到就緒狀態(tài),此時(shí)此線程并不一定會(huì)馬上得以執(zhí)行,這取決于CPU調(diào)度時(shí)機(jī)。
第二種:實(shí)現(xiàn)Runnable接口,并重寫(xiě)該接口的run()方法。創(chuàng)建Runnable實(shí)現(xiàn)類(lèi)的實(shí)例,并以此實(shí)例作為Thread類(lèi)的target來(lái)創(chuàng)建Thread對(duì)象,該Thread對(duì)象才是真正的線程對(duì)象。
class MyRunnable implements Runnable {
private int i = 0;
@Override
public void run() {
for (i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
public class ThreadDemo2 {
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
if (i == 30) {
// 創(chuàng)建一個(gè)Runnable實(shí)現(xiàn)類(lèi)的對(duì)象
Runnable myRunnable = new MyRunnable();
// 將myRunnable作為T(mén)hread target創(chuàng)建新的線程
Thread thread1 = new Thread(myRunnable);
Thread thread2 = new Thread(myRunnable);
// 調(diào)用start()方法使得線程進(jìn)入就緒狀態(tài)
thread1.start();
thread2.start();
}
}
}
}第三種:使用Callable和Future接口創(chuàng)建線程。
- 1:創(chuàng)建Callable接口的實(shí)現(xiàn)類(lèi) ,并實(shí)現(xiàn)Call方法
- 2:創(chuàng)建Callable實(shí)現(xiàn)類(lèi)的實(shí)現(xiàn),使用FutureTask類(lèi)包裝Callable對(duì)象,該
FutureTask對(duì)象封裝了Callable對(duì)象的Call方法的返回值 - 3:使用FutureTask對(duì)象作為T(mén)hread對(duì)象的target創(chuàng)建并啟動(dòng)線程
- 4:調(diào)用FutureTask對(duì)象的get()來(lái)獲取子線程執(zhí)行結(jié)束的返回值\
public class ThreadDemo3 {
public static void main(String[] args) {
// 創(chuàng)建MyCallable對(duì)象
Callable<Integer> myCallable = new MyCallable();
//使用FutureTask來(lái)包裝MyCallable對(duì)象
FutureTask<Integer> ft = new FutureTask<Integer>(myCallable);
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
if (i == 30) {
//FutureTask對(duì)象作為T(mén)hread對(duì)象的target創(chuàng)建新的線程
Thread thread = new Thread(ft);
//線程進(jìn)入到就緒狀態(tài)
thread.start();
}
}
System.out.println("主線程for循環(huán)執(zhí)行完畢..");
try {
//取得新創(chuàng)建的新線程中的call()方法返回的結(jié)果
int sum = ft.get();
System.out.println("sum = " + sum);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
class MyCallable implements Callable<Integer> {
private int i = 0;
// 與run()方法不同的是,call()方法具有返回值
@Override
public Integer call() {
int sum = 0;
for (; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
sum += i;
}
return sum;
}
}首先,我們發(fā)現(xiàn),在實(shí)現(xiàn)Callable接口中,此時(shí)不再是run()方法了,而是call()方法,此call()方法作為線程執(zhí)行體,同時(shí)還具有返回值!在創(chuàng)建新的線程時(shí),是通過(guò)FutureTask來(lái)包裝MyCallable對(duì)象,同時(shí)作為了Thread對(duì)象的target。
第四種:通過(guò)線程池創(chuàng)建線程。
public class ThreadDemo4{
//線程池?cái)?shù)量
private static int POOL_NUM = 10;
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
ExecutorService executorService = Executors.newFixedThreadPool(5);
for(int i = 0; i<POOL_NUM; i++) {
RunnableThread thread = new RunnableThread();
//Thread.sleep(1000);
executorService.execute(thread);
}
//關(guān)閉線程池
executorService.shutdown();
}
}
class RunnableThread implements Runnable {
@Override
public void run() {
System.out.println("通過(guò)線程池方式創(chuàng)建的線程:" + Thread.currentThread().getName() + " ");
}
}ExecutorService、Callable都是屬于Executor框架。返回結(jié)果的線程是在JDK1.5中引入的新特征,還有Future接口也是屬于這個(gè)框架,有了這種特征得到返回值就很方便了。
通過(guò)分析可以知道,他同樣也是實(shí)現(xiàn)了Callable接口,實(shí)現(xiàn)了Call方法,所以有返回值。這也就是正好符合了前面所說(shuō)的兩種分類(lèi)
執(zhí)行Callable任務(wù)后,可以獲取一個(gè)Future的對(duì)象,在該對(duì)象上調(diào)用get就可以獲取到Callable任務(wù)返回的Object了。get方法是阻塞的,
即:線程無(wú)返回結(jié)果,get方法會(huì)一直等待。
到此這篇關(guān)于分享Java多線程實(shí)現(xiàn)的四種方式的文章就介紹到這了,更多相關(guān)Java多線程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于hibernate實(shí)現(xiàn)的分頁(yè)技術(shù)實(shí)例分析
這篇文章主要介紹了基于hibernate實(shí)現(xiàn)的分頁(yè)技術(shù),結(jié)合實(shí)例形式分析了Hibernate分頁(yè)技術(shù)的原理,實(shí)現(xiàn)步驟與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-03-03
微信公眾號(hào)開(kāi)發(fā)之設(shè)置自定義菜單實(shí)例代碼【java版】
這篇文章主要介紹了微信公眾號(hào)開(kāi)發(fā)之設(shè)置自定義菜單實(shí)例代碼,本實(shí)例是為了實(shí)現(xiàn)在管理后臺(tái)實(shí)現(xiàn)微信菜單的添加刪除管理。需要的朋友可以參考下2018-06-06
Java中如何編寫(xiě)一個(gè)數(shù)的n次方(冪運(yùn)算)?
本文介紹了使用pow函數(shù)和自定義for循環(huán)計(jì)算冪的O(n)時(shí)間復(fù)雜度方法,然后重點(diǎn)講解了快速冪算法的分治思想,以及從二進(jìn)制角度的解釋,包括如何通過(guò)位運(yùn)算和循環(huán)迭代實(shí)現(xiàn)高效計(jì)算,給出了Java代碼實(shí)現(xiàn)2024-07-07
spring boot 實(shí)現(xiàn)阿里云視頻點(diǎn)播功能(刪除視頻)
這篇文章主要介紹了spring boot 實(shí)現(xiàn)阿里云視頻點(diǎn)播(刪除視頻功能),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
淺析SpringMVC中的適配器HandlerAdapter
這篇文章主要介紹了SpringMVC中的適配器HandlerAdapter的相關(guān)資料,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
Java五種方式實(shí)現(xiàn)多線程循環(huán)打印問(wèn)題
本文主要介紹了Java五種方式實(shí)現(xiàn)多線程循環(huán)打印問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12
注入jar包里的對(duì)象,用@autowired的實(shí)例
這篇文章主要介紹了注入jar包里的對(duì)象,用@autowired的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
詳解Spring Boot 配置多個(gè)RabbitMQ
本篇文章主要介紹了Spring Boot 配置多個(gè)RabbitMQ,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06

