成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

死磕 Java線程系列之創(chuàng)建線程的8種方式

開(kāi)發(fā) 后端
創(chuàng)建線程,是多線程編程中最基本的操作,彤哥總結(jié)了一下,大概有8種創(chuàng)建線程的方式,你知道嗎?

 

簡(jiǎn)介

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

繼承Thread類并重寫(xiě)run()方法

 

  1. public class CreatingThread01 extends Thread {  
  2.     @Override  
  3.     public void run() {  
  4.         System.out.println(getName() + " is running");  
  5.     }  
  6.     public static void main(String[] args) {  
  7.         new CreatingThread01().start();  
  8.         new CreatingThread01().start();  
  9.         new CreatingThread01().start();  
  10.         new CreatingThread01().start();  
  11.     }  

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

實(shí)現(xiàn)Runnable接口

 

  1. public class CreatingThread02 implements Runnable {  
  2.     @Override  
  3.     public void run() {  
  4.         System.out.println(Thread.currentThread().getName() + " is running");  
  5.     }  
  6.     public static void main(String[] args) {  
  7.         new Thread(new CreatingThread02()).start();  
  8.         new Thread(new CreatingThread02()).start();  
  9.         new Thread(new CreatingThread02()).start();  
  10.         new Thread(new CreatingThread02()).start();  
  11.     }  

實(shí)現(xiàn)Runnable接口,這種方式的好處是一個(gè)類可以實(shí)現(xiàn)多個(gè)接口,不影響其繼承體系。

匿名內(nèi)部類

 

  1. public class CreatingThread03 {  
  2.     public static void main(String[] args) {  
  3.         // Thread匿名類,重寫(xiě)Thread的run()方法  
  4.         new Thread() {  
  5.             @Override  
  6.             public void run() {  
  7.                 System.out.println(getName() + " is running");  
  8.             }  
  9.         }.start();  
  10.         // Runnable匿名類,實(shí)現(xiàn)其run()方法  
  11.         new Thread(new Runnable() {  
  12.             @Override  
  13.             public void run() {  
  14.                 System.out.println(Thread.currentThread().getName() + " is running");  
  15.             }  
  16.         }).start();       
  17.         // 同上,使用lambda表達(dá)式函數(shù)式編程  
  18.         new Thread(()-> 
  19.             System.out.println(Thread.currentThread().getName() + " is running");  
  20.         }).start();  
  21.     }  

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

實(shí)現(xiàn)Callabe接口

 

  1. public class CreatingThread04 implements Callable<long> {  
  2.     @Override  
  3.     public Long call() throws Exception {  
  4.         Thread.sleep(2000);  
  5.         System.out.println(Thread.currentThread().getId() + " is running");  
  6.         return Thread.currentThread().getId();  
  7.     }  
  8.     public static void main(String[] args) throws ExecutionException, InterruptedException {  
  9.         FutureTask<long> task = new FutureTask&lt;&gt;(new CreatingThread04());  
  10.         new Thread(task).start();  
  11.         System.out.println("等待完成任務(wù)");  
  12.         Long result = task.get();  
  13.         System.out.println("任務(wù)結(jié)果:" + result);  
  14.     }  

實(shí)現(xiàn)Callabe接口,可以獲取線程執(zhí)行的結(jié)果,F(xiàn)utureTask實(shí)際上實(shí)現(xiàn)了Runnable接口。

定時(shí)器(java.util.Timer)

 

  1. public class CreatingThread05 {  
  2.     public static void main(String[] args) {  
  3.         Timer timer = new Timer();  
  4.         // 每隔1秒執(zhí)行一次  
  5.         timer.schedule(new TimerTask() {  
  6.             @Override  
  7.             public void run() {  
  8.                 System.out.println(Thread.currentThread().getName() + " is running");  
  9.             }  
  10.         }, 0 , 1000);  
  11.     }  

使用定時(shí)器java.util.Timer可以快速地實(shí)現(xiàn)定時(shí)任務(wù),TimerTask實(shí)際上實(shí)現(xiàn)了Runnable接口。

線程池

 

  1. public class CreatingThread06 {  
  2.     public static void main(String[] args) {  
  3.         ExecutorService threadPool = Executors.newFixedThreadPool(5);  
  4.         for (int i = 0; i &lt; 100; i++) {  
  5.             threadPool.execute(()-&gt; System.out.println(Thread.currentThread().getName() + " is running"));  
  6.         }  
  7.     }  

使用線程池的方式,可以復(fù)用線程,節(jié)約系統(tǒng)資源。

并行計(jì)算(Java8+)

 

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

使用并行計(jì)算的方式,可以提高程序運(yùn)行的效率,多線程并行執(zhí)行。

Spring異步方法

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

 

  1. @SpringBootApplication  
  2. @EnableAsync  
  3. public class Application {  
  4.     public static void main(String[] args) {  
  5.         SpringApplication.run(Application.class, args);  
  6.     }  

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

 

  1. @Service  
  2. public class CreatingThread08Service {  
  3.     @Async  
  4.     public void call() {  
  5.         System.out.println(Thread.currentThread().getName() + " is running");  
  6.     }  

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

 

  1. @RunWith(SpringRunner.class)  
  2. @SpringBootTest(classes = Application.class)  
  3. public class CreatingThread08Test {  
  4.     @Autowired  
  5.     private CreatingThread08Service creatingThread08Service;  
  6.     @Test  
  7.     public void test() {  
  8.         creatingThread08Service.call();  
  9.         creatingThread08Service.call();  
  10.         creatingThread08Service.call();  
  11.         creatingThread08Service.call();  
  12.     }  

運(yùn)行結(jié)果如下:

 

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

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

使用Spring異步方法的方式,可以說(shuō)是相當(dāng)?shù)胤奖悖m用于前后邏輯不相關(guān)聯(lián)的適合用異步調(diào)用的一些方法,比如發(fā)送短信的功能。

總結(jié)

(1)繼承Thread類并重寫(xiě)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類并重寫(xiě)其run()方法,一種是實(shí)現(xiàn)Runnable接口的run()方法,那么它們之間到底有什么聯(lián)系呢?

請(qǐng)看下面的例子,同時(shí)繼承Thread并實(shí)現(xiàn)Runnable接口,應(yīng)該輸出什么呢?

 

  1. public class CreatingThread09 {  
  2.     public static void main(String[] args) {  
  3.         new Thread(()-&gt; {  
  4.             System.out.println("Runnable: " + Thread.currentThread().getName());  
  5.         }) {  
  6.             @Override  
  7.             public void run() {  
  8.                 System.out.println("Thread: " + getName());  
  9.             }  
  10.         }.start();  
  11.     }  

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

 

  1. public class Thread implements Runnable {  
  2.     // Thread維護(hù)了一個(gè)Runnable的實(shí)例  
  3.     private Runnable target;     
  4.     public Thread() { 
  5.          init(null, null, "Thread-" + nextThreadNum(), 0);  
  6.     }    
  7.     public Thread(Runnable target) {  
  8.         init(null, target, "Thread-" + nextThreadNum(), 0);  
  9.     }    
  10.     private void init(ThreadGroup g, Runnable target, String name,  
  11.                       long stackSize, AccessControlContext acc,  
  12.                       boolean inheritThreadLocals) {  
  13.         // ...  
  14.         // 構(gòu)造方法傳進(jìn)來(lái)的Runnable會(huì)賦值給target  
  15.         this.target = target;  
  16.         // ...  
  17.     }    
  18.     @Override  
  19.     public void run() {  
  20.         // Thread默認(rèn)的run()方法,如果target不為空,會(huì)執(zhí)行target的run()方法  
  21.         if (target != null) {  
  22.             target.run();  
  23.         }  
  24.     }  

看到這里是不是豁然開(kāi)朗呢?既然上面的例子同時(shí)繼承Thread并實(shí)現(xiàn)了Runnable接口,根據(jù)源碼,實(shí)際上相當(dāng)于重寫(xiě)了Thread的run()方法,在Thread的run()方法時(shí)實(shí)際上跟target都沒(méi)有關(guān)系了。

所以,上面的例子輸出結(jié)果為T(mén)hread: Thread-0,只輸出重寫(xiě)Thread的run()方法中的內(nèi)容。

 

 

責(zé)任編輯:龐桂玉 來(lái)源: 中國(guó)開(kāi)源
相關(guān)推薦

2010-03-18 15:31:13

Java創(chuàng)建線程

2023-06-07 13:49:00

多線程編程C#

2018-04-02 14:29:18

Java多線程方式

2020-12-17 05:52:09

線程池ThreadPoolThreadPoolE

2024-11-04 09:39:08

Java?接口Thread?類

2017-04-17 19:31:03

Android多線程

2023-06-06 08:17:52

多線程編程Thread類

2024-02-26 08:28:24

Java線程CPU

2023-06-08 08:21:08

多線程編程線程間通信

2022-11-02 15:00:03

Java值傳遞引用傳遞

2010-07-14 10:30:26

Perl多線程

2010-03-15 17:56:23

Java多線程

2025-01-14 07:00:00

線程池ExecutorsJava

2019-10-29 19:49:48

Java線程安全

2021-03-01 08:02:55

算法排序操作

2010-02-02 14:32:32

Python線程編程

2024-02-05 12:08:07

線程方式管理

2011-06-24 11:12:39

Qt 多線程 線程

2011-06-24 11:03:31

Qt 多線程 線程

2023-06-09 07:59:37

多線程編程鎖機(jī)制
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 久久久999免费视频 999久久久久久久久6666 | 日韩成人 | 激情a | 久久i| 给我免费的视频在线观看 | 亚洲欧美一区二区三区在线 | 午夜看电影在线观看 | 精品久久一 | 成人性视频免费网站 | 亚洲精品一区二区三区在线 | 成人精品一区二区三区四区 | 亚洲日本欧美日韩高观看 | 久久久久国产 | 欧美第一页 | 欧美一区二区三区的 | 日韩波多野结衣 | 中文字幕日韩一区 | 国产中文 | 91视频进入| 色偷偷噜噜噜亚洲男人 | 久久91精品国产 | 成人免费一区二区三区视频网站 | 成人无遮挡毛片免费看 | 美女在线一区二区 | 日韩av一二三区 | 国产日韩精品一区二区三区 | 亚洲视频在线播放 | 中文字幕 国产精品 | 7799精品视频天天看 | 91视频一区二区三区 | 丝袜久久 | 国产一级片在线观看视频 | 在线第一页| 男人的天堂久久 | 国产探花在线精品一区二区 | 久久国产综合 | 天天操天天摸天天爽 | 国产一区二区三区欧美 | 激情福利视频 | 日本不卡免费新一二三区 | 精品视频一区二区三区四区 |