日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java线程的6种状态

發布時間:2023/12/4 java 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java线程的6种状态 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

線程的概念,以及線程的創建方式,見我之前寫的博文

本篇文章主要講Java線程的6種狀態

6種狀態:初始狀態(new) 、可運行狀態(Runnable)、運行狀態(Running)、阻塞狀態(Blocked)、死亡狀態(Dead)、等待隊列

初始狀態(New)
進程剛創建,未調用new Thread().start()方法時的狀態,進程創建方式

可運行狀態(Runnable)
在創建線程并調用start()方法之后,獲得CPU運行時間之前的狀態

進入Runnable狀態的方式:

  • 調用線程的start()方法
  • 當前線程sleep()方法結束
  • 其他線程join()結束
  • 等待用戶輸入完畢(阻塞式IO,拿到IO結果后)
  • 當前線程拿到所需鎖
  • 當前線程時間片耗盡
  • 調用當前線程的yield()方法
  • 運行中狀態Running
    獲得CPU運行時間后,運行中的狀態

    進入Running狀態的方式(唯一):

  • 操作系統的線程調度程序,從可運行狀態的線程池中,選出當前線程去執行;
  • 阻塞狀態Blocked
    運行中的線程,可以會由于各種原因進入到阻塞狀態。如調用sleep()方法讓線程睡眠,調用wait()方法讓線程等待,調用join()、suspend()方法(已棄用)或者阻塞式IO。

    進入阻塞狀態的方式:

  • 當前線程調用sleep()方法
  • 當前線程執行過程中,調用了其他線程的join()方法,當前線程進入阻塞狀態
  • 等待阻塞式IO時
  • 死亡狀態Dead
    無論是正常退出(run()方法執行完畢),還是拋出了未捕獲的異常,都會導致線程進入Dead狀態。
    或者是主線程main方法執行完畢
    在一個死去的線程上調用start()方法,會拋出java.lang.IllegalThreadStateException異常

    線程的狀態流轉圖

    線程睡眠:sleep()方法

    線程睡眠,指的是讓當前線程暫停執行,等到指定時間后再恢復執行(Runnable狀態)

  • 線程睡眠會交出CPU,讓給其他線/進程執行
  • sleep()方法不會釋放鎖,即當前線程持有某個對象鎖時,即使調用sleep()方法其他線程也無法訪問這個對象。
  • 調用sleep(),當前線程從Running到blocked,sleep結束,從blocked到Runnable
  • public static native void sleep(long millis) throws InterruptedException;

    線程讓步:yield()方法

    線程讓步,指的是讓當前線程暫停執行,并執行其他線程
    與sleep()的區別在于

  • yield()方法無法控制具體交出CPU的時間
  • yield()方法只能讓擁有相同優先級的線程獲得CPU執行的機會
  • yield()方法讓當前線程進入Runnable狀態
  • yield()方法:

    public static native void yield();

    等待線程終止:join()方法

    等待線程終止,指的是:主線程中調用該方法,就會讓調用該方法的線程先執行,等執行結束后,再回到主線程繼續執行。(即等待,調用join()方法的線程執行完畢后,再執行)

    join()方法:

    public final void join() throws InterruptedException {//join帶參數指的是等待的超時時間,為0代表永久等待join(0);}

    wait()方法

    obj.wait(),當前線程調用對象的wait()方法,當前線程釋放對象鎖,進入等待隊列。依靠notify()/notifyAll()喚醒或者wait(long timeout)timeout時間到自動喚醒

    public final void wait() throws InterruptedException {}public final native void wait(long timeout) throws InterruptedException;

    notify()方法

    obj.notify()喚醒在此對象監視器上等待的單個線程,選擇是任意性的。notifyAll()喚醒在此對象監視器上等待的所有線程

    public final native void notify();public final native void notifyAll();

    線程停止的3種方式

    1):設置標志位,讓線程正常停止

    class MyThread1 extends Thread {private boolean flag = false;@Overridepublic void run() {int i=0;while (!flag) {System.out.println("線程循環執行次數:"+i);}} }

    2):使用stop方法強制線程停止,不安全,已廢棄!

    stop方法:

    @Deprecatedpublic final void stop() {}

    為什么stop()不安全?

    因為stop()會解除相應線程持有的所有鎖,并且當在線程對象上執行stop方法時,會立即停止該線程

    比如當正在執行如下同步方法時,執行到x=10,線程調用了stop()方法,那就會進入不一致的狀態,所以線程不安全

    public synchronized void f() {x =10;y =20; }

    3):調用interrupt()方法

    調用Thread類的interrupted()方法,其本質只是設置該線程的中斷標志,將中斷標志設置為true,并根據線程狀態決定是否拋出異常。因此,通過interrupted()方法真正實現線程的中斷原理是 :開發人員根據中斷標志的具體值來決定如何退出線程。

    interrupt()方法

    public void interrupt() {}

    拓展:

    為什么notify(), wait()等函數定義在Object中,而不是Thread中

    Object中的wait(), notify()等函數,和synchronized一樣,會對“對象的同步鎖”進行操作。

    wait()會使“當前線程”等待,因為線程進入等待狀態,所以線程應該釋放它鎖持有的“同步鎖”,否則其它線程獲取不到該“同步鎖”而無法運行!
    OK,線程調用wait()之后,會釋放它鎖持有的“同步鎖”;而且,根據前面的介紹,我們知道:等待線程可以被notify()或notifyAll()喚醒。現在,請思考一個問題:notify()是依據什么喚醒等待線程的?或者說,wait()等待線程和notify()之間是通過什么關聯起來的?答案是:依據“對象的同步鎖”。

    負責喚醒等待線程的那個線程(我們稱為“喚醒線程”),它只有在獲取“該對象的同步鎖”(這里的同步鎖必須和等待線程的同步鎖是同一個),并且調用notify()或notifyAll()方法之后,才能喚醒等待線程。雖然,等待線程被喚醒;但是,它不能立刻執行,因為喚醒線程還持有“該對象的同步鎖”。必須等到喚醒線程釋放了“對象的同步鎖”之后,等待線程才能獲取到“對象的同步鎖”進而繼續運行。

    總之,notify(), wait()依賴于“同步鎖”,而“同步鎖”是對象鎖持有,并且每個對象有且僅有一個!這就是為什么notify(), wait()等函數定義在Object類,而不是Thread類中的原因。

    總結

    以上是生活随笔為你收集整理的Java线程的6种状态的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。