wait,notify,sleep,yield,join方法的實現

前言

在閱讀本篇文章以前建議先看看,[Java內存模型和volatile、synchronized] (www.jianshu.com/p/ad43ac258…)中介紹過的Java虛擬機對每一個對象實現的monitor鎖。java

wait

  1. 調用wait方法能將當前線程阻塞掉,直到調用notify或者notifyAll方法來讓線程從新去嘗試獲取鎖(即喚醒線程)。
  2. wait方法是一個本地方法,它是經過一個monitor對象鎖來實現的,只有擁有了該對象的監視器鎖才能調用wait方法,那麼怎麼調用wait方法呢?
  3. 是經過增長synchronized關鍵字來實現的,這也是爲何wait必須在synchronized修飾的代碼中運行的緣由。但只要調用了wait方法,monitor鎖就會被立刻釋放掉。

notify

與wait同理也必須在有synchronized關鍵字修飾的代碼中才可以調用,一樣都是當前對象調用。spa

sleep

  1. 使用sleep方法會讓線程暫停,也須要synchronized關鍵字,但只是讓出了CPU的時間片,並無釋放掉monitor鎖。
  2. 調用sleep的線程是順序進入的,當前一個線程尚未執行完的時候,後面一個線程是不可能執行同步方法的。
  3. 當wait方法不一樣,由於它調用後就立刻釋放掉monitor鎖了,因此其餘線程就可以獲取到鎖,執行當前對象的調用。當以前調用wait方法的線程被喚醒後,才能繼續是參與鎖的競爭(注意:這裏並非說能立刻獲取到鎖,是獲取到鎖以後才能進行執行)。

yield

  1. 當一個線程正在執行的時候,它擁有最高的優先級。
  2. 當調用yield方法時,JVM可能會把運行機會給其餘擁有相同優先級的線程,也可能不會由於yield只是提出個建議並無強制切換線程。
  3. 當切換線程後,當前調用yield的線程進行到可運行狀態,而不是等待或阻塞狀態。

join

阻塞當前正在執行的進程,執行調用join方法的線程,執行完畢後,再去喚醒當前線程。線程

補充:爲何wait方法在Object類中,Sleep在Thread類中?

這二者的施加者是有本質區別的.

  1. sleep()是讓某個線程暫停運行一段時間,其控制範圍是由當前線程決定,也就是說,在線程裏面決定.
  2. wait()是由某個肯定的對象來調用的
  • 二者均可以讓線程暫停一段時間,可是本質的區別是一個線程的運行狀態控制,一個是線程之間的通信的問題

sleep和wait之間區別有:

  1. 這兩個方法來自不一樣的類分別是Thread和Object
  2. 最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其餘線程可使用同步控制塊或者方法。
  3. wait,notify和notifyAll只能在同步控制方法或者同步控制塊裏面使用,而sleep能夠在任何地方使用
synchronized(x){
      x.notify()
     //或者wait()
   }
複製代碼
  1. sleep必須捕獲異常,而wait,notify和notifyAll不須要捕獲異常
相關文章
相關標籤/搜索