爲什麼wait()和notify()需要搭配synchonized關鍵字使用(三)

理解此問題先修知識:

synchronized 的含義:

  • Java中每一個對象都可以成爲一個監視器(Monitor), 該Monitor由一個鎖(lock), 一個等待隊列(waiting
    queue ), 一個入口隊列( entry queue).
  • 對於一個對象的方法, 如果沒有synchronized關鍵字, 該方法可以被任意數量的線程,在任意時刻調用。
  • 對於添加了synchronized關鍵字的方法,任意時刻只能被唯一的一個獲得了對象實例鎖的線程調用。
  • synchronized用於實現多線程的同步操作

wait()功用

  • wait(), notify(), notifyAll() 和 synchonized 需要搭配使用, 用於線程同步
  • wait()總是在一個循環中被調用,掛起當前線程來等待一個條件的成立。 Wait調用會一直等到其他線程調用notifyAll()時才返回。
  • 當一個線程在執行synchronized 的方法內部,調用了wait()後, 該線程會釋放該對象的鎖,
    然後該線程會被添加到該對象的等待隊列中(waiting queue), 只要該線程在等待隊列中, 就會一直處於閒置狀態, 不會被調度執行。
    要注意wait()方法會強迫線程先進行釋放鎖操作,所以在調用wait()時,
    該線程必須已經獲得鎖,否則會拋出異常。由於wait()在synchonized的方法內部被執行, 鎖一定已經獲得, 就不會拋出異常了。

notify()的功用

  • wait(), notify(), notifyAll() 和 synchonized 需要搭配使用, 用於線程同步
  • 當一個線程調用一個對象的notify()方法時, 調度器會從所有處於該對象等待隊列(waiting queue)的線程中取出任意一個線程,
    將其添加到入口隊列( entry queue) 中. 然後在入口隊列中的多個線程就會競爭對象的鎖, 得到鎖的線程就可以繼續執行。
    如果等待隊列中(waiting queue)沒有線程, notify()方法不會產生任何作用
  • notifyAll() 和notify()工作機制一樣, 區別在於notifyAll()會將等待隊列(waiting
    queue)中所有的線程都添加到入口隊列中(entry queue)
  • 注意, notifyAll()比notify()更加常用, 因爲notify()方法只會喚起一個線程,
    且無法指定喚醒哪一個線程,所以只有在多個執行相同任務的線程在併發運行時, 我們不關心哪一個線程被喚醒時,纔會使用notify()

正確寫法

// 線程 A 的代碼
synchronized(obj_A)
{
	while(!condition){ 
	    obj_A.wait();
	}
	// do something 
}

// 線程 B 的代碼
synchronized(obj_A)
{
	if(!condition){ 
		// do something ...
	    condition = true;
	    obj_A.notify();
	}
}

————————————————
版權聲明:本文爲CSDN博主「蕭蕭冷」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/lengxiao1993/article/details/52296220

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章