Thread的run()與start()的區別
Java的執行緒是通過java.lang.Thread類來實現的。VM啟動時會有一個由主方法所定義的執行緒。可以通過建立Thread的例項來建立新的執行緒。每個執行緒都是通過某個特定Thread物件所對應的方法run()來完成其操作的,方法run()稱為執行緒體。通過呼叫Thread類的start()方法來啟動一個執行緒。
在Java當中,執行緒通常都有五種狀態,建立、就緒、執行、阻塞和死亡。
第一是建立狀態。在生成執行緒物件,並沒有呼叫該物件的start方法,這是執行緒處於建立狀態。
第二是就緒狀態。當呼叫了執行緒物件的start方法之後,該執行緒就進入了就緒狀態,但是此時執行緒排程程式還沒有把該執行緒設定為當前執行緒,此時處於就緒狀態。線上程執行之後,從等待或者睡眠中回來之後,也會處於就緒狀態。
第三是執行狀態。執行緒排程程式將處於就緒狀態的執行緒設定為當前執行緒,此時執行緒就進入了執行狀態,開始執行run函式當中的程式碼。
第四是阻塞狀態。執行緒正在執行的時候,被暫停,通常是為了等待某個時間的發生(比如說某項資源就緒)之後再繼續執行。sleep,suspend,wait等方法都可以導致執行緒阻塞。
第五是死亡狀態。如果一個執行緒的run方法執行結束或者呼叫stop方法後,該執行緒就會死亡。對於已經死亡的執行緒,無法再使用start方法令其進入就緒。
實現並啟動執行緒有兩種方法
1、寫一個類繼承自Thread類,重寫run方法。用start方法啟動執行緒
2、寫一個類實現Runnable介面,實現run方法。用new Thread(Runnable target).start()方法來啟動
多執行緒原理:
相當於玩遊戲機,只有一個遊戲機(cpu),可是有很多人要玩,於是,start是排隊!等CPU選中你就是輪到你,你就run(),當CPU的執行的時間片執行完,這個執行緒就繼續排隊,等待下一次的run()。
呼叫start()後,執行緒會被
放到等待佇列,等待CPU排程,
並不一定要馬上開始執行,只是將這個執行緒置於可動行狀態。然後通過JVM,執行緒Thread會呼叫run()方法,執行本執行緒的執行緒體。
先呼叫start後呼叫run,這麼麻煩,為了不直接呼叫run?
就是為了實現多執行緒的優點,沒這個start不行。
1.start()方法來啟動執行緒,真正實現了多執行緒執行。
這時無需等待run方法體程式碼執行完畢,可以直接繼續執行下面的程式碼;通過呼叫Thread類的start()方法來啟動一個執行緒, 這時此執行緒是處於就緒狀態, 並沒有執行。 然後通過此Thread類呼叫方法run()來完成其執行操作的, 這裡方法run()稱為執行緒體,它包含了要執行的這個執行緒的內容, Run方法執行結束, 此執行緒終止。然後CPU再排程其它執行緒。
2.run()方法當作普通方法的方式呼叫。
程式還是要順序執行,要等待run方法體執行完畢後,才可繼續執行下面的程式碼; 程式中只有主執行緒——這一個執行緒, 其程式執行路徑還是隻有一條, 這樣就沒有達到寫執行緒的目的。
記住:多執行緒就是分時利用CPU,巨集觀上讓所有執行緒一起執行 ,也叫併發
public class Test {
public static void main(String[] args) {
Runner1 runner1 = new Runner1();
Runner2 runner2 = new Runner2();
// Thread(Runnable target) 分配新的 Thread 物件。
Thread thread1 = new Thread(runner1);
Thread thread2 = new Thread(runner2);
// thread1.start();
// thread2.start();
thread1.run();
thread2.run();
}
}
class Runner1 implements Runnable { // 實現了Runnable介面,jdk就知道這個類是一個執行緒
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("進入Runner1執行狀態——————————" + i);
}
}
}
class Runner2 implements Runnable { // 實現了Runnable介面,jdk就知道這個類是一個執行緒
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("進入Runner2執行狀態==========" + i);
}
}
}
相關文章
- docker run 與docker start的區別,為容器命名Docker
- java面試題之Thread的run()和start()方法有什麼區別Java面試題thread
- JNI-Thread中start方法的呼叫與run方法的回撥分析thread
- Thread中run和start方法的模板設計模式thread設計模式
- 【HBase】start master 與 start master --backup 的區別AST
- 為啥呼叫new Thread().start()方法會呼叫run()方法?thread
- RMAN run命令塊中的logseq與sequence的區別Gse
- Thread和Runnable的區別thread
- Thread 和runnable的區別thread
- Java_Thread類的sleep()與SystemClock類的sleep()的區別Javathread
- Android中Handler Runnable與Thread的區別詳解Androidthread
- npm run dev 和 npm run serve 區別NPMdev
- Dockerfile 中 RUN, CMD, ENTRYPOINT 的區別Docker
- Java中Runnable和Thread的區別Javathread
- Java 中Thread 和Runnable的區別Javathread
- Task.Run(async () =>{}) 和 Task.Run(() =>{})區別
- crsctl start/stop crs and crsctl start/stop cluster 區別
- 轉android-Service和Thread的區別Androidthread
- rac中 crsctl start/stop crs and crsctl start/stop cluster 區別
- ??與?:的區別
- java執行緒系列---Runnable和Thread的區別Java執行緒thread
- MySQL的@與@@區別MySql
- mybatis #與$的區別MyBatis
- Null 與 “” 的區別Null
- docker-compose up start restart區別DockerREST
- in與exist , not in與not exist 的區別
- Hystrix semaphore和thread隔離策略的區別及配置參thread
- CentOS 與 Ubuntu 的區別CentOSUbuntu
- artice與section的區別
- GET 與 POST 的區別
- WebSocket 與 Socket 的區別Web
- Postgresql與MySQL的區別MySql
- chown與chmod的區別
- session與cookie的區別SessionCookie
- LESS與SASS的區別
- free 與 CFRelease 的區別
- gulp與webpack的區別Web
- @Autowired 與@Resource的區別