偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

10 張圖聊聊線程的生命周期和常用 APIs

系統(tǒng)
今天我們來說一下線程的生命周期和常用 APIs:我們需要非常清楚的知道線程的各種狀態(tài),比如排查程序運(yùn)行慢的原因時(shí),就需要看下是不是哪里被阻塞了;另外它也是面試時(shí)非常喜歡問的,如果基礎(chǔ)內(nèi)容都答不好,恐怕直接就掛了。

[[341272]]

 今天我們來說一下線程的生命周期和常用 APIs:我們需要非常清楚的知道線程的各種狀態(tài),比如排查程序運(yùn)行慢的原因時(shí),就需要看下是不是哪里被阻塞了;另外它也是面試時(shí)非常喜歡問的,如果基礎(chǔ)內(nèi)容都答不好,恐怕直接就掛了。

本文分為兩大部分,

1.線程的 6 大狀態(tài);

2.多線程常用的 APIs:

  • join()
  • wait()
  • notify()
  • yield()
  • sleep()
  • currentThread()
  • getName()
  • getId()
  • getPriority()
  • setPriority()
  • stop()

線程狀態(tài)

關(guān)于線程的狀態(tài),網(wǎng)上各種說法都有,比較流行的是 5 種或者 6 種。關(guān)于 5 種狀態(tài)的那個(gè)版本我沒有找到理論依據(jù),如果有小伙伴清楚的也歡迎留言指出。

我這里所寫的是根據(jù) java.lang.Thread 的源碼,線程有以下 6 大狀態(tài):

  1. public enum State { 
  2.   NEW, 
  3.   RUNNABLE, 
  4.   BLOCKED, 
  5.   WAITTING, 
  6.   TIMED_WAITTING, 
  7.   TERMINATED; 

先上圖,我們再依次來看。

 

1. New

A thread that has not yet started is in this state.

就是指線程剛創(chuàng)建,還沒啟動(dòng)的時(shí)候,比如剛 new 了一個(gè) thread。

  1. MyThread myThread = new MyThread(); 

2. Runnable

A thread is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.

那么接下來,自然就是要啟動(dòng)線程了,也就是調(diào)用 thread 的 start() 方法。

  1. myThread.start(); 

啟動(dòng)之后,線程就進(jìn)入了 Runnable 狀態(tài)。

此時(shí)所有的線程都會(huì)添加到一個(gè)等待隊(duì)列里,等待“CPU 調(diào)度”。

如果搶占到 CPU 的資源,那就執(zhí)行;如果沒搶到,就等著唄,等當(dāng)前正在執(zhí)行的線程完成它能執(zhí)行的時(shí)間片之后,再次搶占。

要注意這里在等待的一般是系統(tǒng)資源,而不是鎖或者其他阻塞。

3. Blocked

Thread state for a thread blocked waiting for a monitor lock.

A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling wait() Object.

這里給出了非常明確的 use case,就是被鎖在外面的才叫阻塞。所以這里必須要有至少 2 個(gè)線程。

4. Waiting

A thread in the waiting state is waiting for another thread to perform a particular action.

那具體有哪些原因呢?

A thread is in the waiting state due to calling one of the following methods:

  • Object.wait with no timeout
  • Thread.join with no timeout
  • LockSupport.park

所以說,當(dāng)調(diào)用了

  • wait(),
  • join(),
  • park()

方法之后,線程進(jìn)入等待狀態(tài)。

這里的等待狀態(tài)是沒有時(shí)間限制的,可以無限的等下去... 所以需要有人來喚醒:

如果是通過 wait() 進(jìn)入等待狀態(tài)的,需要有 notify() 或者 notifyAll() 方法來喚醒;

如果是通過 join() 進(jìn)入等待狀態(tài)的,需要等待目標(biāo)線程運(yùn)行結(jié)束。

比如在生產(chǎn)者消費(fèi)者模型里,當(dāng)沒有商品的時(shí)候,消費(fèi)者就需要等待,等待生產(chǎn)者生產(chǎn)好了商品發(fā) notify()。下一篇文章我們會(huì)細(xì)講。

5. Timed_waiting

導(dǎo)致這個(gè)狀態(tài)的原因如下:

  • Thread.sleep
  • Object.wait with timeout
  • Thread.join with timeout
  • LockSupport.parkNanos
  • LockSupport.parkUntil

其實(shí)就是在上一種狀態(tài)的基礎(chǔ)上,給了具體的時(shí)間限制。

那么當(dāng)時(shí)間結(jié)束后,線程就解放了。

6. Terminated

A thread that has exited is in this state.

這里有 3 種情況會(huì)終止線程:

  • 執(zhí)行完所有代碼,正常結(jié)束;
  • 強(qiáng)制被結(jié)束,比如調(diào)用了 stop() 方法,現(xiàn)在已經(jīng)被棄用;
  • 拋出了未捕獲的異常。

線程一旦死亡就不能復(fù)生。

如果在一個(gè)死去的線程上調(diào)用 start() 方法,那么程序會(huì)拋出 java.lang.IllegalThreadStateException。

接下來我們說說多線程中常用的 11 個(gè) APIs。

APIs

1. join()

join() 方法會(huì)強(qiáng)制讓該線程執(zhí)行,并且一直會(huì)讓它執(zhí)行完。

比如上一篇文章的例子是兩個(gè)線程交替執(zhí)行的,那么我們這里該下,改成調(diào)用小齊線程.join(),那么效果就是先輸出 小齊666。

  1. public class MyRunnable implements Runnable { 
  2.     @Override 
  3.     public void run() { 
  4.         for(int i = 0; i < 100; i++) { 
  5.             System.out.println("小齊666:" + i); 
  6.         } 
  7.     } 
  8.  
  9.     public static void main(String[] args) throws InterruptedException { 
  10.         Thread t = new Thread(new MyRunnable()); 
  11.         t.start(); 
  12.         t.join(); 
  13.  
  14.         for(int i = 0; i < 100; i++) { 
  15.             System.out.println("主線程" + i + ":齊姐666"); 
  16.         } 
  17.     } 

 

所以 join() 能夠保證某個(gè)線程優(yōu)先執(zhí)行,而且會(huì)一直讓它執(zhí)行完,再回歸到公平競爭狀態(tài)。

join() 方法其實(shí)是用 wait() 來實(shí)現(xiàn)的,我們來看下這個(gè)方法。

2. wait() and notify()

wait() 其實(shí)并不是 Thread 類的方法,而是 Object 里面的方法。

該方法就是讓當(dāng)前對(duì)象等待,直到另一個(gè)對(duì)象調(diào)用 notify() 或者 notifyAll()。

當(dāng)然了,我們也可以設(shè)定一個(gè)等待時(shí)長,到時(shí)間之后對(duì)象將會(huì)自動(dòng)蘇醒。

4. yield()

yield 本身的中文意思是屈服,用在這里倒也合適。

yield() 表示當(dāng)前線程主動(dòng)讓出 CPU 資源一下,然后我們再一起去搶。

注意這里讓一下真的只是一下,從“執(zhí)行中”回到“等待 CPU 分配資源”,然后所有線程再一起搶占資源。

5. sleep()

顧名思義,這個(gè)方法就是讓當(dāng)前線程睡一會(huì),比如說,

  1. myThread.sleep(1000); // 睡眠 1 秒鐘 

它會(huì)拋出一個(gè) InterruptedException 異常,所以還要 try catch 一下。

6. currentThread()

Returns a reference to the currently executing thread object.

該方法是獲取當(dāng)前線程對(duì)象。

注意它是一個(gè) static 方法,所以直接通過 Thread 類調(diào)用。

比如打印當(dāng)前線程

  1. System.out.println(Thread.currentThread()); 

前文的例子中,它會(huì)輸出:

  1. Thread[Thread-0,5,main] 
  2. Thread[main,5,main] 

沒錯(cuò),它的返回值也是 Thread 類型。

7. getName()

該方法可以獲取當(dāng)前線程名稱。

這個(gè)名稱可以自己設(shè)置,比如:

  1. Thread t = new Thread(new MyRunnable(), "壹齊學(xué)"); 

8. getId()

該方法是獲取線程的 Id.

9. getPriority()

線程也有優(yōu)先級(jí)的哦~

雖然優(yōu)先級(jí)高的線程并不能百分百保證一定會(huì)先執(zhí)行,但它是有更大的概率被先執(zhí)行的。

優(yōu)先級(jí)的范圍是 1-10,我們來看源碼:

  1. /** 
  2.     * The minimum priority that a thread can have. 
  3.     */ 
  4.    public final static int MIN_PRIORITY = 1; 
  5.  
  6.   /** 
  7.     * The default priority that is assigned to a thread. 
  8.     */ 
  9.    public final static int NORM_PRIORITY = 5; 
  10.  
  11.    /** 
  12.     * The maximum priority that a thread can have. 
  13.     */ 
  14.    public final static int MAX_PRIORITY = 10; 

如果不在這個(gè)范圍,JDK 拋出 IllegalArgumentException() 的異常。

10. setPriority()

當(dāng)然啦,我們也是可以自己設(shè)置某個(gè)線程的優(yōu)先級(jí)的。

設(shè)置的優(yōu)先級(jí)也需要在規(guī)定的 1-10 的范圍內(nèi)哦,如果不在這個(gè)范圍也會(huì)拋異常。

11. stop()

最后我們來說下 stop() 方法,也是前文提到過的強(qiáng)制停止線程的一種方式,但現(xiàn)在已被棄用,因?yàn)闀?huì)引起一些線程安全方面的問題。

 

好了,以上就是有關(guān)線程狀態(tài)和常用 API 的介紹了。相信大家看完之后對(duì)線程的整個(gè)流程應(yīng)該有了清晰的認(rèn)識(shí),其實(shí)里面還有很多細(xì)節(jié)我沒有展開,畢竟這是多線程的第 2 講,更深入的內(nèi)容我們慢慢來。

本文轉(zhuǎn)載自微信公眾號(hào)「 碼農(nóng)田小齊」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系 碼農(nóng)田小齊公眾號(hào)。

 

責(zé)任編輯:武曉燕 來源: 碼農(nóng)田小齊
相關(guān)推薦

2023-10-26 08:25:35

Java線程周期

2023-09-12 10:52:16

OpenSSL開源套件

2010-07-14 10:48:37

Perl線程

2009-06-18 13:32:39

Java線程生命周期

2012-01-16 09:00:56

線程

2020-02-10 19:34:12

生命周期流程流程圖

2010-07-14 10:59:15

Perl線程

2009-06-29 18:03:15

Java多線程線程的生命周期

2015-07-08 16:28:23

weak生命周期

2022-04-19 07:20:24

軟件開發(fā)安全生命周期SSDLC應(yīng)用安全

2009-06-11 11:28:35

JSF生命周期

2023-12-18 08:24:56

ViewModel數(shù)據(jù)操作Android

2012-04-28 13:23:12

Java生命周期

2011-06-16 09:31:21

ActivityAndroid

2021-02-20 07:23:32

Windows10操作系統(tǒng)微軟

2012-06-20 10:29:16

敏捷開發(fā)

2009-06-24 10:47:55

JSF生命周期

2013-08-19 17:03:00

.Net生命周期對(duì)象

2021-07-19 05:52:29

網(wǎng)絡(luò)生命周期網(wǎng)絡(luò)框架

2020-03-30 13:20:58

線程Java編程語言
點(diǎn)贊
收藏

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