中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Thread線程中基礎知識及常見疑惑點有哪些

發布時間:2021-08-19 13:58:14 來源:億速云 閱讀:102 作者:小新 欄目:編程語言

小編給大家分享一下Thread線程中基礎知識及常見疑惑點有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

正文

1、Thread線程的狀態

根據《深入理解Java虛擬機》一書的講述,Java語言定義了五種線程狀態,分別為:創建(new)、運行(Runnable)、等待(waiting)、阻塞(blocked)、結束(terminated)。而且規定,在某一個時間點,每個線程能且只能處于其中的一種狀態。

其中,運行狀態又包括就緒(Ready)跟正在運行(Running),區別就是是否獲得了CPU的執行時間。

對于等待跟阻塞狀態,需要著重說明一下,因為此處極易搞錯,而且也是面試常被問到的點。等待狀態,一般由Object.wait()、Thread.sleep()、Thread.join()、LockSupport.park()等方法以及這些方法帶時間控制的同類方法實現線程的等待。而阻塞狀態,一般是由于當前線程還未獲取到獨占鎖且正在等待獲取,此時稱為阻塞。可以將等待看做主動的線程暫停執行,以為需要調用特定的方法線程才會等待;而阻塞可以看做是被動的線程暫定執行,因為線程在等著獲取獨占鎖。

2、Thread線程的相關方法

start()方法/run()方法:有時在面試的時候,面試官會問到調用線程的start方法跟直接調用run方法有什么區別?雖然有的道友看到這里會覺得問這種問題的面試官有點很沒必要,但我還是說一下。調用start方法后,最終會調用Thread類中的一個本地方法start0,這個方法可以新建一個線程來運行你的run方法,而調用run方法后只是在當前線程上運行你的run方法,并沒有新線程參與。

wait()方法/sleep()方法:請注意,這里很多人都會記錯,wait方法以及跟它配套的notify/notifyAll方法,是位于頂級父類Object下的,而其他操作線程的方法都在Thread線程類下。為什么要將wait方法放在Object下呢?其實這是由wait/notify方法的實現原理決定的。wait方法調用了之后,會釋放鎖,并讓當前線程等待,而對于java的原生鎖synchronized,是隸屬于一個特定對象的監視器monitor的,那這個釋放的是鎖誰的鎖?不能是別人的,只能是調用wait方法的那個對象的。而這個鎖是哪里來的?要釋放鎖,肯定之前加過鎖,在哪里加的呢?只能是在synchronized塊中給這個對象加的,所以這也解釋了為什么wait/notify方法一直要跟synchronized一起用,因為它倆就是通過操作對象的鎖實現的等待和喚醒。相比而言sleep方法單純很多,它只是讓當前線程睡眠一段時間,并不會涉及到對鎖的操作,所以直接放在Thread類中就行。對于wait跟notify的演示如下:

public static void main(String[] args) throws InterruptedException {
    Object obj = new Object();
    Thread thread = new Thread(new Runnable() {
      @Override
      public void run() {
        synchronized (obj) {
          try {
            System.out.println("thread獲取到鎖,觸發wait");
            obj.wait();
            System.out.println("wait over");
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }
    });
    Thread thread1 = new Thread(new Runnable() {
      @Override
      public void run() {
        synchronized (obj) {
          try {
            System.out.println("thread1獲取到鎖");
            Thread.sleep(1000);
            System.out.println("1秒后喚醒");
            obj.notify();
          } catch (Exception e) {
            e.printStackTrace();
          }
          System.out.println("notify over");
        }

      }
    });
    thread.start();
    thread1.start();
  }

執行結果為:

thread獲取到鎖,觸發wait
thread1獲取到鎖
1秒后喚醒
notify over
wait over

LockSupport.park():另外還有JUC包中的park方法讓當前線程等待。此方法是使用CAS實現的線程等待,不會釋放鎖。而park/unpark方法比wait/notify這一對好的地方在于,前者可以先unpark在park,這是線程仍然會繼續執行;而對于wait/notify,則需要通過程序控制執行順序,一定要先wait在notify/notifyAll,否則順序反了線程就會一直等待下去,由此悲劇誕生... 比如講上述wait/notify的代碼34行35行調換一下順序,執行結果如下所示:

thread1獲取到鎖
1秒后喚醒
notify over
thread獲取到鎖,觸發wait

仿佛云天明對程心那一千八百萬年的等待

join()/yield():對于Thread下的這兩個方法,之所以放在一起講解,就是因為這兩個方法平時比較少用到,屬于閑云野鶴的存在。

yield()方法是讓當前線程讓步,讓步的意思就是放棄執行權,即當前線程會從上述說的運行狀態runnable中的running狀態進入ready就緒狀態,但是虛擬機不保證當前線程執行了yield方法后不會緊接著再次進去running狀態,因為可能CPU分配執行時間時又分給了當前線程。所以這個方法其實一般也沒啥用,因為效果不穩定。

join()方法是將調用join的線程插入當前線程的執行過程中,即讓當前線程等待,先執行完調用join的線程,再繼續執行當前線程。注意join方法不會釋放鎖。join的演示代碼如下:

public class RunnableThread implements Runnable{
  @Override
  public void run() {
    System.out.println("runnable run");
    try {
      System.out.println("開始睡眠");
      Thread.sleep(5000);
      System.out.println("睡了5秒");
    } catch (Exception e) {
      System.out.println("runnable exception:" + e);
    }
  }

  public static void main(String[] args) throws InterruptedException {
    Object obj = new Object();
    Thread thread = new Thread(new RunnableThread());
    thread.start();
    thread.join();
    System.out.println("end");
  }
}

執行結果為:

runnable run
開始睡眠
睡了5秒
end

以上是“Thread線程中基礎知識及常見疑惑點有哪些”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

万山特区| 剑川县| 临夏县| 湟中县| 南充市| 临泽县| 疏勒县| 秦安县| 囊谦县| 阜新| 札达县| 额敏县| 黄平县| 邵阳市| 衡东县| 康平县| 永昌县| 桑日县| 醴陵市| 墨江| 金门县| 罗甸县| 朝阳区| 绩溪县| 县级市| 木里| 南宫市| 安溪县| 东明县| 泰宁县| 建平县| 隆化县| 邢台县| 尚义县| 安顺市| 伊通| 昭通市| 扎囊县| 邵阳县| 泾阳县| 金门县|