日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

詳解JAVA 線程-線程的狀態有哪些?它是如何工作的?

瀏覽:139日期:2022-08-30 17:39:00

線程(Thread)是并發編程的基礎,也是程序執行的最小單元,它依托進程而存在。

一個進程中可以包含多個線程,多線程可以共享一塊內存空間和一組系統資源,因此線程之間的切換更加節省資源、更加輕量化,也因此被稱為輕量級的進程。

線程的狀態在 JDK 1.5 之后以枚舉的方式被定義在 Thread 的源碼中,它總共包含以下 6 個狀態:

NEW,新建狀態,線程被創建出來,但尚未啟動時的線程狀態; RUNNABLE,就緒狀態,表示可以運行的線程狀態,它可能正在運行,或者是在排隊等待操作系統給它分配 CPU 資源; BLOCKED,阻塞等待鎖的線程狀態,表示處于阻塞狀態的線程正在等待監視器鎖,比如等待執行 synchronized 代碼塊或者使用 synchronized 標記的方法; WAITING,等待狀態,一個處于等待狀態的線程正在等待另一個線程執行某個特定的動作,比如,一個線程調用了 Object.wait() 方法,那它就在等待另一個線程調用 Object.notify() 或 Object.notifyAll() 方法; TIMED_WAITING,計時等待狀態,和等待狀態(WAITING)類似,它只是多了超時時間,比如調用了有超時時間設置的方法 Object.wait(long timeout) 和 Thread.join(long timeout) 等這些方法時,它才會進入此狀態; TERMINATED,終止狀態,表示線程已經執行完成。

線程狀態的源代碼如下:

public enum State { /** * 新建狀態,線程被創建出來,但尚未啟動時的線程狀態 */ NEW, /** * 就緒狀態,表示可以運行的線程狀態,但它在排隊等待來自操作系統的 CPU 資源 */ RUNNABLE, /** * 阻塞等待鎖的線程狀態,表示正在處于阻塞狀態的線程 * 正在等待監視器鎖,比如等待執行 synchronized 代碼塊或者 * 使用 synchronized 標記的方法 */ BLOCKED, /** * 等待狀態,一個處于等待狀態的線程正在等待另一個線程執行某個特定的動作。 * 例如,一個線程調用了 Object.wait() 它在等待另一個線程調用 * Object.notify() 或 Object.notifyAll() */ WAITING, /** * 計時等待狀態,和等待狀態 (WAITING) 類似,只是多了超時時間,比如 * 調用了有超時時間設置的方法 Object.wait(long timeout) 和 * Thread.join(long timeout) 就會進入此狀態 */ TIMED_WAITING, /** * 終止狀態,表示線程已經執行完成 */}

線程的工作模式是,首先先要創建線程并指定線程需要執行的業務方法,然后再調用線程的 start() 方法,此時線程就從 NEW(新建)狀態變成了 RUNNABLE(就緒)狀態;

然后線程會判斷要執行的方法中有沒有 synchronized 同步代碼塊,如果有并且其他線程也在使用此鎖,那么線程就會變為 BLOCKED(阻塞等待)狀態,當其他線程使用完此鎖之后,線程會繼續執行剩余的方法。

當遇到 Object.wait() 或 Thread.join() 方法時,線程會變為 WAITING(等待狀態)狀態;

如果是帶了超時時間的等待方法,那么線程會進入 TIMED_WAITING(計時等待)狀態;

當有其他線程執行了 notify() 或 notifyAll() 方法之后,線程被喚醒繼續執行剩余的業務方法,直到方法執行完成為止,此時整個線程的流程就執行完了,執行流程如下圖所示:

詳解JAVA 線程-線程的狀態有哪些?它是如何工作的?

【BLOCKED 和 WAITING 的區別】

雖然 BLOCKED 和 WAITING 都有等待的含義,但二者有著本質的區別。

首先它們狀態形成的調用方法不同。

其次 BLOCKED 可以理解為當前線程還處于活躍狀態,只是在阻塞等待其他線程使用完某個鎖資源;

而 WAITING 則是因為自身調用了 Object.wait() 或著是 Thread.join() 又或者是 LockSupport.park() 而進入等待狀態,只能等待其他線程執行某個特定的動作才能被繼續喚醒。

比如當線程因為調用了 Object.wait() 而進入 WAITING 狀態之后,則需要等待另一個線程執行 Object.notify() 或 Object.notifyAll() 才能被喚醒。

【start() 和 run() 的區別】

首先從 Thread 源碼來看,start() 方法屬于 Thread 自身的方法,并且使用了 synchronized 來保證線程安全,源碼如下:

public synchronized void start() { // 狀態驗證,不等于 NEW 的狀態會拋出異常 if (threadStatus != 0) throw new IllegalThreadStateException(); // 通知線程組,此線程即將啟動 group.add(this); boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { // 不處理任何異常,如果 start0 拋出異常,則它將被傳遞到調用堆棧上 } }}

run() 方法為 Runnable 的抽象方法,必須由調用類重寫此方法,重寫的 run() 方法其實就是此線程要執行的業務方法,源碼如下:

public class Thread implements Runnable { // 忽略其他方法...... private Runnable target; @Override public void run() { if (target != null) { target.run(); } }}@FunctionalInterfacepublic interface Runnable { public abstract void run();}

從執行的效果來說,start() 方法可以開啟多線程,讓線程從 NEW 狀態轉換成 RUNNABLE 狀態,而 run() 方法只是一個普通的方法。

其次,它們可調用的次數不同,start() 方法不能被多次調用,否則會拋出 java.lang.IllegalStateException;而 run() 方法可以進行多次調用,因為它只是一個普通的方法而已。

【線程優先級】

在 Thread 源碼中和線程優先級相關的屬性有 3 個:

// 線程可以擁有的最小優先級public final static int MIN_PRIORITY = 1;// 線程默認優先級public final static int NORM_PRIORITY = 5;// 線程可以擁有的最大優先級public final static int MAX_PRIORITY = 10

線程的優先級可以理解為線程搶占 CPU 時間片的概率,優先級越高的線程優先執行的概率就越大,但并不能保證優先級高的線程一定先執行。

在程序中我們可以通過 Thread.setPriority() 來設置優先級,setPriority() 源碼如下:

public final void setPriority(int newPriority) { ThreadGroup g; checkAccess(); // 先驗證優先級的合理性 if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { throw new IllegalArgumentException(); } if((g = getThreadGroup()) != null) { // 優先級如果超過線程組的最高優先級,則把優先級設置為線程組的最高優先級 if (newPriority > g.getMaxPriority()) { newPriority = g.getMaxPriority(); } setPriority0(priority = newPriority); }}

【線程的常用方法】

線程的常用方法有以下幾個。

join()

在一個線程中調用 other.join() ,這時候當前線程會讓出執行權給 other 線程,直到 other 線程執行完或者過了超時時間之后再繼續執行當前線程,join() 源碼如下:

public final synchronized void join(long millis)throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; // 超時時間不能小于 0 if (millis < 0) { throw new IllegalArgumentException('timeout value is negative'); } // 等于 0 表示無限等待,直到線程執行完為之 if (millis == 0) { // 判斷子線程 (其他線程) 為活躍線程,則一直等待 while (isAlive()) { wait(0); } } else { // 循環判斷 while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } }}

從源碼中可以看出 join() 方法底層還是通過 wait() 方法來實現的。

例如,在未使用 join() 時,代碼如下:

public class ThreadExample { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(() -> { for (int i = 1; i < 6; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println('子線程睡眠:' + i + '秒。'); } }); thread.start(); // 開啟線程 // 主線程執行 for (int i = 1; i < 4; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println('主線程睡眠:' + i + '秒。'); } }}

程序執行結果為:

復制主線程睡眠:1秒。

子線程睡眠:1秒。

主線程睡眠:2秒。

子線程睡眠:2秒。

主線程睡眠:3秒。

子線程睡眠:3秒。

子線程睡眠:4秒。

子線程睡眠:5秒。

從結果可以看出,在未使用 join() 時主子線程會交替執行。

然后我們再把 join() 方法加入到代碼中,代碼如下:

public class ThreadExample { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(() -> { for (int i = 1; i < 6; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println('子線程睡眠:' + i + '秒。'); } }); thread.start(); // 開啟線程 thread.join(2000); // 等待子線程先執行 2 秒鐘 // 主線程執行 for (int i = 1; i < 4; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println('主線程睡眠:' + i + '秒。'); } }}

程序執行結果為:

復制子線程睡眠:1秒。

子線程睡眠:2秒。

主線程睡眠:1秒。

// thread.join(2000); 等待 2 秒之后,主線程和子線程再交替執行

子線程睡眠:3秒。

主線程睡眠:2秒。

子線程睡眠:4秒。

子線程睡眠:5秒。

主線程睡眠:3秒。

從執行結果可以看出,添加 join() 方法之后,主線程會先等子線程執行 2 秒之后才繼續執行。

yield()

看 Thread 的源碼可以知道 yield() 為本地方法,也就是說 yield() 是由 C 或 C++ 實現的,源碼如下:

public static native void yield();

yield() 方法表示給線程調度器一個當前線程愿意出讓 CPU 使用權的暗示,但是線程調度器可能會忽略這個暗示。

比如我們執行這段包含了 yield() 方法的代碼,如下所示:

public static void main(String[] args) throws InterruptedException { Runnable runnable = new Runnable() { @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println('線程:' + Thread.currentThread().getName() + ' I:' + i); if (i == 5) { Thread.yield(); } } } }; Thread t1 = new Thread(runnable, 'T1'); Thread t2 = new Thread(runnable, 'T2'); t1.start(); t2.start();}

當我們把這段代碼執行多次之后會發現,每次執行的結果都不相同,這是因為 yield() 執行非常不穩定,線程調度器不一定會采納 yield() 出讓 CPU 使用權的建議,從而導致了這樣的結果。

以上就是詳解JAVA 線程-線程的狀態有哪些?它是如何工作的?的詳細內容,更多關于java 線程的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
在线综合亚洲| 久久中文字幕av| 国产亚洲欧美日韩精品一区二区三区| 国产精品成人一区二区网站软件| 高清久久一区| 欧美日韩国产一区二区三区不卡| 国产精品日本欧美一区二区三区| 日韩极品在线观看| 黑森林国产精品av| 美女久久一区| 91成人精品观看| 美女网站视频一区| 日韩 欧美一区二区三区| 老司机精品视频网| 99热精品在线| 国产精品网址| 不卡在线一区| 欧美a在线观看| 1024精品久久久久久久久| 午夜性色一区二区三区免费视频| 激情久久一区二区| 免费在线视频一区| 久久久精品区| 亚洲深爱激情| 精品三区视频| 好看不卡的中文字幕| 欧美精品中文字幕亚洲专区| 日韩国产欧美| 天堂va在线高清一区| 夜鲁夜鲁夜鲁视频在线播放| 视频一区日韩精品| 久久久精品午夜少妇| 欧美久久一区二区三区| 九一国产精品| 精品一区二区三区中文字幕| 9色国产精品| 欧美国产视频| 999在线观看精品免费不卡网站| 久久精品国产久精国产| 免费中文字幕日韩欧美| 精品国产午夜| 亚洲精品日本| 亚洲福利专区| 久久精品一区二区三区中文字幕| 蜜臀av国产精品久久久久| www.51av欧美视频| 日韩国产欧美一区二区三区| 免费国产自久久久久三四区久久| 欧美激情久久久久久久久久久| 国产一区导航| 欧美精品日日操| 国产精品亚洲欧美| 蜜臀av亚洲一区中文字幕| 波多野结衣久久精品| 欧美亚洲一区二区三区| 极品日韩av| 成人影视亚洲图片在线| 国产视频一区二区在线播放| 男人天堂欧美日韩| 欧美.日韩.国产.一区.二区| 国产中文在线播放| 国产精品一区亚洲| 石原莉奈在线亚洲二区| 999久久久亚洲| 国产精品黑丝在线播放| 欧美精品成人| 久久国产精品色av免费看| 亚洲一区二区三区四区电影 | 日韩精品免费视频一区二区三区 | 欧美天堂一区| 亚洲精品影院在线观看| 99国产精品自拍| 欧美福利在线| 91精品啪在线观看国产18| 国产一区二区三区久久| 国产精品视频一区二区三区综合 | 中文字幕色婷婷在线视频| 久久精品国产福利| 国产日韩高清一区二区三区在线 | 视频一区二区国产| 狠狠爱成人网| 欧美日韩黑人| 女人av一区| 99精品网站| аⅴ资源天堂资源库在线| 国产精品自在| 国产亚洲精品精品国产亚洲综合| 天海翼亚洲一区二区三区| 蜜臀久久久99精品久久久久久| 黄页网站一区| 好吊日精品视频| 一区在线免费观看| 精品91久久久久| 欧美日韩精品一本二本三本 | 国产亚洲高清视频| 五月天久久网站| 午夜精品一区二区三区国产| 1024精品久久久久久久久| 九九综合在线| 宅男噜噜噜66国产日韩在线观看| 午夜久久久久| 亚洲免费网址| 亚洲天堂av资源在线观看| 亚洲一区欧美| 日本h片久久| 久久av日韩| аⅴ资源天堂资源库在线| 四虎4545www国产精品| 精品日韩毛片| 首页国产欧美久久| 日本不卡视频一二三区| 日韩欧美久久| 国产精品手机在线播放| 九九99久久精品在免费线bt| 激情黄产视频在线免费观看| 精品三级久久| 亚洲精品网址| 综合色一区二区| 国产欧美日韩精品一区二区免费| 欧美aaaaaa午夜精品| 中国字幕a在线看韩国电影| 久久国产电影| 视频一区视频二区在线观看| 97精品国产99久久久久久免费| 国产日韩欧美高清免费| 欧美国产日韩电影| 日本高清不卡一区二区三区视频 | 日韩一区自拍| 女主播福利一区| 亚洲精品麻豆| 精品理论电影在线| 91精品久久久久久久久久不卡| 久久亚洲风情| 麻豆久久一区| 久久久9色精品国产一区二区三区| 国产女优一区| 国产欧美一区二区色老头| 国产精品久久观看| 免费毛片在线不卡| 日产欧产美韩系列久久99| 精品视频在线观看网站| 九色精品91| 国产日韩在线观看视频| 日韩在线欧美| 亚洲色图网站| 精品视频一区二区三区四区五区 | 日韩精品水蜜桃| 最新亚洲国产| 精品国产亚洲一区二区三区大结局| 久久久久久久久99精品大| 亚洲视频国产精品| 久久精品97| 国产精品一区三区在线观看| 国内精品麻豆美女在线播放视频| 91精品一区二区三区综合在线爱| 欧美日韩国产免费观看视频| 久久亚洲影院| 国产探花在线精品一区二区| 国产精品毛片一区二区在线看| 蜜桃一区二区三区| 日本亚洲视频| 久久亚洲道色| 一区久久精品| 日韩精彩视频在线观看| 老鸭窝一区二区久久精品| 日韩不卡视频在线观看| 老牛影视一区二区三区| 久久国内精品| 久久美女性网| 日本va欧美va瓶| www.51av欧美视频| 中文一区一区三区免费在线观| 免费精品一区| 一区二区自拍| 欧美aa在线视频| 精品一区免费| 国产精品午夜一区二区三区| 欧美午夜精彩| 奇米色欧美一区二区三区| 成人在线视频中文字幕| 99热精品在线观看| 国产精品一线天粉嫩av| 伊人精品一区| 欧美综合社区国产| 日本国产精品| 日韩av电影一区| 国产一在线精品一区在线观看| 欧美日韩中出| 九一精品国产| 麻豆91精品视频| 免费在线欧美视频| 国产资源在线观看入口av| 综合一区av| 日产精品一区二区| 亚洲精品免费观看| 午夜精品成人av| 国产日韩免费| 亚洲资源av| 日韩欧美看国产| 国产精品亚洲综合久久|