欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Thread線程的基礎(chǔ)知識及常見疑惑點總結(jié)

 更新時間:2019年05月26日 11:06:03   投稿:laozhang  
在本篇內(nèi)容里小編給大家分享的是關(guān)于Thread線程的基礎(chǔ)知識及常見疑惑點,對此有學(xué)習(xí)需求的朋友們可以學(xué)習(xí)參考下。

引言

相信各位道友在平時工作中已經(jīng)很少直接用到Thread線程類了,現(xiàn)在大多是通過線程池或者一些多線程框架來操作線程任務(wù),但我覺得還是有必要了解清楚Thread線程類中各種方法的含義,了解了底層才能更好的理解框架、應(yīng)用框架。下面我就將Thread線程的相關(guān)基礎(chǔ)點總結(jié)一二,以供觀瞻。

正文

1、Thread線程的狀態(tài)

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

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

對于等待跟阻塞狀態(tài),需要著重說明一下,因為此處極易搞錯,而且也是面試常被問到的點。等待狀態(tài),一般由Object.wait()、Thread.sleep()、Thread.join()、LockSupport.park()等方法以及這些方法帶時間控制的同類方法實現(xiàn)線程的等待。而阻塞狀態(tài),一般是由于當(dāng)前線程還未獲取到獨占鎖且正在等待獲取,此時稱為阻塞??梢詫⒌却醋鲋鲃拥木€程暫停執(zhí)行,以為需要調(diào)用特定的方法線程才會等待;而阻塞可以看做是被動的線程暫定執(zhí)行,因為線程在等著獲取獨占鎖。

2、Thread線程的相關(guān)方法

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

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

執(zhí)行結(jié)果為:

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

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

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

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

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

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

join()方法是將調(diào)用join的線程插入當(dāng)前線程的執(zhí)行過程中,即讓當(dāng)前線程等待,先執(zhí)行完調(diào)用join的線程,再繼續(xù)執(zhí)行當(dāng)前線程。注意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");
  }
}

執(zhí)行結(jié)果為:

runnable run
開始睡眠
睡了5秒
end

結(jié)束語

這次先到這里,上述說的東西,雖然很小,而且實際中不會直接用到,但是對于我們理解線程的運行機制、理解多線程框架都有好處,所以還是有必要在自己的學(xué)習(xí)地圖上理解清楚。其實線程還有一個很重要的點就是線程的中斷,多線程框架或者JUC包的源碼中都會涉及到對線程中斷的處理以及響應(yīng),這一塊我會在后面梳理清楚了之后專門整理出來。最近覺得學(xué)習(xí)進入了停滯期,有點不知道從何下手,覺得需要學(xué)的東西太多。在這里,想跟各位道友討教一下,一個資質(zhì)普通的開發(fā)者,如何才能將自己的實力提升到一個比較高的層次(比如阿里的P6P7及以上?)歡迎留言賜教,在此不勝感激!

相關(guān)文章

  • 八種Java中的基本數(shù)據(jù)類型詳解

    八種Java中的基本數(shù)據(jù)類型詳解

    在Java編程中,基本數(shù)據(jù)類型是必不可少的一部分,對于初學(xué)者而言,理解這些基本數(shù)據(jù)類型是非常重要的,下面我們就來學(xué)習(xí)一下Java中的八種基本數(shù)據(jù)類型,以及它們的使用方法吧
    2023-08-08
  • 淺析Java中對稱與非對稱加密算法原理與使用

    淺析Java中對稱與非對稱加密算法原理與使用

    密碼學(xué)是研究編制密碼和破譯密碼的技術(shù)科學(xué)。這篇文章主要為大家介紹了Java中對稱與非對稱加密算法的原理與使用,感興趣的小伙伴可以了解一下
    2023-03-03
  • springmvc整合freemarker配置的詳細(xì)步驟

    springmvc整合freemarker配置的詳細(xì)步驟

    本篇文章主要介紹了springmvc整合freemarker的詳細(xì)步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • 詳談spring中bean注入無效和new創(chuàng)建對象的區(qū)別

    詳談spring中bean注入無效和new創(chuàng)建對象的區(qū)別

    這篇文章主要介紹了spring中bean注入無效和new創(chuàng)建對象的區(qū)別,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • sharding-jdbc讀寫分離原理詳細(xì)解析

    sharding-jdbc讀寫分離原理詳細(xì)解析

    這篇文章主要介紹了sharding-jdbc讀寫分離原理詳細(xì)解析,很多時候,為了應(yīng)付DB的高并發(fā)讀寫,我們會采用讀寫分離技術(shù),讀寫分離指的是利用數(shù)據(jù)庫主從技術(shù)(把數(shù)據(jù)復(fù)制到多個節(jié)點中),分散讀多個庫以支持高并發(fā)的讀,需要的朋友可以參考下
    2023-12-12
  • Java 正則表達(dá)式 解釋說明

    Java 正則表達(dá)式 解釋說明

    java正則知識小結(jié),一些常見的正則都包括在里面,推薦收藏。
    2009-06-06
  • java RocketMQ快速入門基礎(chǔ)知識

    java RocketMQ快速入門基礎(chǔ)知識

    這篇文章主要介紹了java RocketMQ快速入門基礎(chǔ)知識,所以RocketMQ是站在巨人的肩膀上(kafka),又對其進行了優(yōu)化讓其更滿足互聯(lián)網(wǎng)公司的特點。它是純Java開發(fā),具有高吞吐量、高可用性、適合大規(guī)模分布式系統(tǒng)應(yīng)用的特點。,需要的朋友可以參考下
    2019-06-06
  • 關(guān)于idea更新到2020.2.3無法創(chuàng)建web項目原因 library is not specified

    關(guān)于idea更新到2020.2.3無法創(chuàng)建web項目原因 library is not specified

    這篇文章主要介紹了關(guān)于idea更新到2020.2.3無法創(chuàng)建web項目原因 library is not specified,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • Java實現(xiàn)多個wav文件合成一個的方法示例

    Java實現(xiàn)多個wav文件合成一個的方法示例

    這篇文章主要介紹了Java實現(xiàn)多個wav文件合成一個的方法,涉及java文件流讀寫、編碼轉(zhuǎn)換、解析等相關(guān)操作技巧,需要的朋友可以參考下
    2019-05-05
  • JavaWeb頁面中防止點擊Backspace網(wǎng)頁后退情況

    JavaWeb頁面中防止點擊Backspace網(wǎng)頁后退情況

    當(dāng)鍵盤敲下后退鍵(Backspace)后怎么防止網(wǎng)頁后退情況呢?今天小編通過本文給大家詳細(xì)介紹下,感興趣的朋友一起看看吧
    2016-11-11

最新評論