中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

8種創建Java線程的方式,你知道幾個?

發布時間:2020-06-28 02:45:16 來源:網絡 閱讀:410 作者:架構師追風 欄目:編程語言

作者:唐彤

簡介

創建線程,是多線程編程中最基本的操作,彤哥總結了一下,大概有8種創建線程的方式,你知道嗎?

8種創建Java線程的方式,你知道幾個?

1.繼承Thread類并重寫run()方法

public?class?CreatingThread01?extends?Thread?{
?@Override
?public?void?run()?{
?System.out.println(getName()?+?"?is?running");
?}
?public?static?void?main(String[]?args)?{
?new?CreatingThread01().start();
?new?CreatingThread01().start();
?new?CreatingThread01().start();
?new?CreatingThread01().start();
?}
}

繼承Thread類并重寫run()方法,這種方式的弊端是一個類只能繼承一個父類,如果這個類本身已經繼承了其它類,就不能使用這種方式了。

2.實現Runnable接口

public?class?CreatingThread02?implements?Runnable?{
?@Override
?public?void?run()?{
?System.out.println(Thread.currentThread().getName()?+?"?is?running");
?}
?public?static?void?main(String[]?args)?{
?new?Thread(new?CreatingThread02()).start();
?new?Thread(new?CreatingThread02()).start();
?new?Thread(new?CreatingThread02()).start();
?new?Thread(new?CreatingThread02()).start();
?}
}

實現Runnable接口,這種方式的好處是一個類可以實現多個接口,不影響其繼承體系。

3.匿名內部類

public?class?CreatingThread03?{
?public?static?void?main(String[]?args)?{
?//?Thread匿名類,重寫Thread的run()方法
?new?Thread()?{
?@Override
?public?void?run()?{
?System.out.println(getName()?+?"?is?running");
?}
?}.start();
?//?Runnable匿名類,實現其run()方法
?new?Thread(new?Runnable()?{
?@Override
?public?void?run()?{
?System.out.println(Thread.currentThread().getName()?+?"?is?running");
?}
?}).start();
?//?同上,使用lambda表達式函數式編程
?new?Thread(()->{
?System.out.println(Thread.currentThread().getName()?+?"?is?running");
?}).start();
?}
}

使用匿名類的方式,一是重寫Thread的run()方法,二是傳入Runnable的匿名類,三是使用lambda方式,現在一般使用第三種(java8+),簡單快捷。

4.實現Callabe接口

public?class?CreatingThread04?implements?Callable<Long>?{
?@Override
?public?Long?call()?throws?Exception?{
?Thread.sleep(2000);
?System.out.println(Thread.currentThread().getId()?+?"?is?running");
?return?Thread.currentThread().getId();
?}
?public?static?void?main(String[]?args)?throws?ExecutionException,?InterruptedException?{
?FutureTask<Long>?task?=?new?FutureTask<>(new?CreatingThread04());
?new?Thread(task).start();
?System.out.println("等待完成任務");
?Long?result?=?task.get();
?System.out.println("任務結果:"?+?result);
?}
}

實現Callabe接口,可以獲取線程執行的結果,FutureTask實際上實現了Runnable接口。

8種創建Java線程的方式,你知道幾個?

5.定時器(java.util.Timer)

public?class?CreatingThread05?{
?public?static?void?main(String[]?args)?{
?Timer?timer?=?new?Timer();
?//?每隔1秒執行一次
????????timer.schedule(new?TimerTask()?{
?@Override
?public?void?run()?{
?System.out.println(Thread.currentThread().getName()?+?"?is?running");
?}
?},?0?,?1000);
?}
}

使用定時器java.util.Timer可以快速地實現定時任務,TimerTask實際上實現了Runnable接口。

6.線程池

public?class?CreatingThread06?{
?public?static?void?main(String[]?args)?{
?ExecutorService?threadPool?=?Executors.newFixedThreadPool(5);
?for?(int?i?=?0;?i?<?100;?i++)?{
????????????threadPool.execute(()->?System.out.println(Thread.currentThread().getName()?+?"?is?running"));
?}
?}
}

使用線程池的方式,可以復用線程,節約系統資源。

7.并行計算(Java8+)

public?class?CreatingThread07?{
?public?static?void?main(String[]?args)?{
?List<Integer>?list?=?Arrays.asList(1,?2,?3,?4,?5);
?//?串行,打印結果為12345
????????list.stream().forEach(System.out::print);
?System.out.println();
?//?并行,打印結果隨機,比如35214
????????list.parallelStream().forEach(System.out::print);
?}
}

使用并行計算的方式,可以提高程序運行的效率,多線程并行執行。

8.Spring異步方法

首先,springboot啟動類加上 @EnableAsync注解(@EnableAsync是spring支持的,這里方便舉例使用springboot)。

@SpringBootApplication
@EnableAsync
public?class?Application?{
?public?static?void?main(String[]?args)?{
?SpringApplication.run(Application.class,?args);
?}
}

其次,方法加上 @Async注解。

@Service
public?class?CreatingThread08Service?{
?@Async
?public?void?call()?{
?System.out.println(Thread.currentThread().getName()?+?"?is?running");
?}
}

然后,測試用例直接跟使用一般的Service方法一模一樣。

@RunWith(SpringRunner.class)
@SpringBootTest(classes?=?Application.class)
public?class?CreatingThread08Test?{
?@Autowired
?private?CreatingThread08Service?creatingThread08Service;
?@Test
?public?void?test()?{
????????creatingThread08Service.call();
????????creatingThread08Service.call();
????????creatingThread08Service.call();
????????creatingThread08Service.call();
?}
}

運行結果如下:

task-3?is?running
task-2?is?running
task-1?is?running
task-4?is?running

可以看到每次執行方法時使用的線程都不一樣。

使用Spring異步方法的方式,可以說是相當地方便,適用于前后邏輯不相關聯的適合用異步調用的一些方法,比如發送短信的功能。

歡迎大家關注我的公種浩【程序員追風】,文章都會在里面更新,整理的資料也會放在里面。

總結

(1)繼承Thread類并重寫run()方法;

(2)實現Runnable接口;

(3)匿名內部類;

(4)實現Callabe接口;

(5)定時器(java.util.Timer);

(6)線程池;

(7)并行計算(Java8+);

(8)Spring異步方法;

8種創建Java線程的方式,你知道幾個?

福利

上面介紹了那么多創建線程的方式,其實本質上就兩種,一種是繼承Thread類并重寫其run()方法,一種是實現Runnable接口的run()方法,那么它們之間到底有什么聯系呢?

請看下面的例子,同時繼承Thread并實現Runnable接口,應該輸出什么呢?

public?class?CreatingThread09?{
?public?static?void?main(String[]?args)?{
?new?Thread(()->?{
?System.out.println("Runnable:?"?+?Thread.currentThread().getName());
?})?{
?@Override
?public?void?run()?{
?System.out.println("Thread:?"?+?getName());
?}
?}.start();
?}
}

說到這里,我們有必要看一下Thread類的源碼:

public?class?Thread?implements?Runnable?{
?//?Thread維護了一個Runnable的實例
?private?Runnable?target;
?public?Thread()?{
????????init(null,?null,?"Thread-"?+?nextThreadNum(),?0);
?}
?public?Thread(Runnable?target)?{
????????init(null,?target,?"Thread-"?+?nextThreadNum(),?0);
?}
?private?void?init(ThreadGroup?g,?Runnable?target,?String?name,
?long?stackSize,?AccessControlContext?acc,
?boolean?inheritThreadLocals)?{
?//?...
?//?構造方法傳進來的Runnable會賦值給target
?this.target?=?target;
?//?...
?}
?@Override
?public?void?run()?{
?//?Thread默認的run()方法,如果target不為空,會執行target的run()方法
?if?(target?!=?null)?{
????????????target.run();
?}
?}
}

看到這里是不是豁然開朗呢?既然上面的例子同時繼承Thread并實現了Runnable接口,根據源碼,實際上相當于重寫了Thread的run()方法,在Thread的run()方法時實際上跟target都沒有關系了。

所以,上面的例子輸出結果為 Thread:Thread-0,只輸出重寫Thread的run()方法中的內容。

最后

歡迎大家一起交流,喜歡文章記得點個贊喲,感謝支持!


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

格尔木市| 诸城市| 曲阳县| 大埔县| 枝江市| 镇远县| 龙川县| 台东县| 乡城县| 方正县| 南江县| 长宁区| 涪陵区| 集安市| 佳木斯市| 平武县| 西安市| 虹口区| 安义县| 五莲县| 始兴县| 剑阁县| 梓潼县| 余姚市| 平遥县| 六盘水市| 石棉县| 乳山市| 鄂尔多斯市| 洪泽县| 屏边| 恩平市| 平顺县| 乌什县| 婺源县| 阳城县| 通江县| 保德县| 新密市| 兴安县| 巴楚县|