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

妹子問我為啥啟動線程時使用 Start 而不是 Run

網絡 通信技術
今天團隊里面的妹子問阿粉,為什么在啟動線程的時候,都使用 start 方法,而不是 run 方法呢?

[[357639]]

 本文轉載自微信公眾號「Java極客技術」,作者鴨血粉絲。轉載本文請聯系Java極客技術公眾號。   

今天團隊里面的妹子問阿粉,為什么在啟動線程的時候,都使用 start 方法,而不是 run 方法呢

還好阿粉平時一直有在學習,要不真的被妹子問住了

在多線程中,如果想讓一個線程啟動,你使用的方法一定是 thread.start() 方法,而不是 thread.run() 方法(啥,你用的不是 thread.start() 方法?乖,你的打開方式不對哦,下次不要這樣了

有沒有疑惑,為什么每次我們都習慣調用 start() 方法,為什么不直接調用 run() 方法來啟動線程呢?

而且如果去看源碼的話,你會發現,在 thread.start() 方法中,其實最后還是調用了 thread.run() 方法來執行

  1. Causes this thread to begin execution; the Java Virtual Machine 
  2.  calls the <code>run</code> method of this thread. 

上面的注釋翻譯一下:當線程開始執行時, JVM 會調用此線程的 run 方法

也就是說,線程的 run 方法是由 JVM 直接調用的,在 Java 中如果我們想要直接調用 run 方法也是可以的,因為在 Java 中 run 方法是 public 的

  1. @Override 
  2.    public void run() { 
  3.        if (target != null) { 
  4.            target.run(); 
  5.        } 
  6.    } 

那既然 start 方法最后調用的也是 run 方法,再加上 run 方法本身支持直接調用,那為啥我們平時寫的程序都是調用 start 方法,而不是 run 方法呢

那是因為,如果直接調用 run 方法,就不是多線程了

為了方便解釋,咱們看個小 demo :

  1. public class RunThread { 
  2.     public static void main(String[] args) { 
  3.         Thread runThread = new Thread(new Runnable() { 
  4.             @Override 
  5.             public void run() { 
  6.                 System.out.printf("Run begin another , 當前線程 : %s.%n" ,Thread.currentThread().getName()); 
  7.             } 
  8.         }); 
  9.  
  10.         // 啟動線程 
  11.         runThread.start(); 
  12.  
  13.         // 直接調用 run 方法 -- 演示使用,實際中不要這么做! 
  14.         runThread.run(); 
  15.  
  16.         System.out.printf("Run begin , 當前線程 : %s.%n" ,Thread.currentThread().getName()); 
  17.     } 

上面的程序運行結果如下:

你會發現, runThread 的 run 方法被執行了兩次

一次是 run 方法運行在自己的線程中,從 Run begin another , 當前線程 : Thread-0 可以看到,這個線程是運行在 Thread-0 中

另外一次是因為我們的程序代碼直接調用了 run 方法,此時的線程運行在 main 線程中,從 Run begin another , 當前線程 : main 可以看出來

也就是說,如果我們直接調用 run 方法的話,線程并不是運行在自己的線程中,而是運行在了當前線程中

我們為什么要創建多線程?不就是希望多個線程并行執行,比如現在我是線程 A ,此時又起了一個線程,那么我希望這個線程是和線程 A 一起運行的,如果直接調用了 run 方法的話,就運行在線程 A 里面來了

并沒有達到創建多線程的目標,這怎么行呢,對不對

所以在啟動線程時,都是使用 start 方法,而不是 run 方法

這一點,其實在源碼中也有說明:

the Java Virtual Machine calls the run method of this thread.

The result is that two threads are running concurrently:

the current thread (which returns from the call to the start method)

and the other thread (which executes its run method).

在 JVM 調用線程的 run 方法之后,結果就是兩個線程同時運行:

  • 當前線程(從調用返回到 start 方法)
  • 另一個線程(執行 run 方法)

一個線程能不能 start 兩次?

妹子搞懂了為什么線程一般都使用 start 方法,不使用 run 方法,因為調用的話,就違背了我們想要用多線程去處理的初衷

妹子又問阿粉,那一個線程是不是可以 start 兩次呢?

負責任的阿粉趕緊告訴小妹妹是不可以的

如果一個線程啟動兩次,想都不用想會拋出 IllegalThreadStateException 這個異常

這個錯誤我們也能在源碼中看到:

  1. if (threadStatus != 0) 
  2.     throw new IllegalThreadStateException(); 

線程開始 start 時,會首先判斷 threadStatus 的值是否為 0 ,如果值不是 0 的話,說明這個線程的 state 狀態不是 new 就拋出 IllegalThreadStateException 異常

啊?竟然還想問阿粉,線程的狀態除了 new 還有什么?阿粉以前寫過一篇,要不要看看:面試官沒想到,一個 Java 線程生命周期,我可以扯半小時

 

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2020-05-12 08:56:16

Java 線程開發

2024-08-01 10:10:24

MySQL場景搜索

2022-09-05 15:36:47

線程方法Java

2023-03-29 09:01:46

HSBRGB模型

2013-03-25 10:14:18

NginxApache

2022-02-15 07:03:04

start 源碼run線程

2019-08-28 12:31:31

戴爾

2020-10-26 07:07:50

線程安全框架

2020-07-24 09:20:44

MapObject前端

2020-11-26 10:58:08

線程啟動

2020-09-15 09:23:19

C++WindowsC#

2021-02-26 05:30:25

元素For-Each代碼

2021-03-26 11:50:28

Linuxexals

2023-03-01 10:42:58

gRPC服務端設置

2021-06-30 12:47:12

標簽HTML分辨率

2022-05-02 17:34:25

大數據數據分析

2022-12-02 14:00:55

CIO交付能力

2023-06-14 16:40:31

LinuxWSL

2024-02-20 20:12:09

C語言字符串Redis

2022-05-09 19:59:15

RedisLRU 算法
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: h视频在线观看免费 | 毛片免费在线 | 国产一区二区精品在线观看 | 免费观看黄色片视频 | 亚洲视频 欧美视频 | 在线视频中文字幕 | 欧美激情一区二区 | 在线视频 亚洲 | 成人免费大片黄在线播放 | 欧美偷偷操| 亚洲国产成人精品久久久国产成人一区 | 久久精品亚洲精品国产欧美kt∨ | 亚洲免费网站 | 久久小视频| 亚洲在线一区 | 韩国av电影网| 一区二区三区免费 | 国产在线资源 | 不卡一区二区三区四区 | 国产女人与拘做视频免费 | 国产成人亚洲精品 | 国产美女免费视频 | 欧美成人一级 | 色婷婷综合网 | yiren22综合网成人 | 日本视频一区二区三区 | 蜜臀网| 久久精选 | 国产视频久久久 | 亚洲毛片| 亚洲福利片| 精品美女视频在线观看免费软件 | 精品国产三级 | 久久久91 | 91新视频 | 国产丝袜人妖cd露出 | 国产成人精品综合 | 影音先锋中文字幕在线观看 | 亚洲一区二区三区免费在线观看 | 一级毛毛片| 免费观看一级特黄欧美大片 |