Java併發之線程互斥與線程同步的概念(純理論)

線程互斥與線程同步

通常情況下,程序中的多個線程是互相協調和互相聯繫的,多線程之間有互斥和同步。

 

1.線程互斥(鎖)我幹完,你再來幹

多個線程之間有共享資源(shared resource)時會出現互斥現象。

設有若干線程共享某個變量,而且都對共享變量有修改。如果它們之間不考慮相互協調工作,就會產生混亂。比如,線程A和B共用變量x,都對x執行增1操作。由於A和B沒有協調,兩線程對x的讀取、修改和寫入操作相互交叉,可能兩個線程讀取相同個x值,一個線程將修改後的x新值寫入到x後,另一個線程也把自己對x修改後的新值寫入到x。這樣,x只記錄最後一個線程的修改作用。

 

臨界段:多線程互斥使用共享資源的程序段,在操作系統中稱爲臨界段。臨界段是一種加鎖的機制,與多線程共享資源(共享變量)有關。

臨界段的作用是在任何時刻一個共享資源(共享變量)只能供一個線程使用。當資源未被佔用,線程可以進入處理這個共享資源的臨界段,從而得到該資源的使用權;當線程執行完畢,便退出臨界段。如果一個線程已進入某個共享資源,並且還沒有使用結束,其他線程必須等待。

爲實現線程互斥,在JAVA中使用關鍵字synchronized來定義臨界段,能對共享對象(共享變量)進行上鎖操作。

 

2.線程同步(wait、notify)我等你做完事,你再通知我做事

多線程之間除了有互斥情況外,還有線程同步。當線程A使用某個對象(共享變量),而此對象(共享變量)又需要線程B修改後才能符合本線程的需要,此時線程A就要等待線程B完成修改工作,這種線程的相互等待稱爲線程同步。

 

爲實現線程同步,在JAVA中提供了Object下的wait()、notify()和notifyAll()三個方法供線程在臨界段中使用。

在臨界段中使用wait()方法,使執行該方法的線程等待,並允許其他線程使用這個臨界段。wait()常用兩種格式:

  wait()——讓線程一直處於等待隊列(WAITING SET?),直到被其他線程使用了同一個對象的notify()或notifyAll()方法喚醒

  wait(long timeout)——讓線程等待到timeout時間後自動喚醒,或被notify通知

當線程使用完臨界段後,用notify()方法通知由於想使用這個臨界段而處於等待狀態的線程結束等待。notify()方法只是通知第一個處於等待的線程(隨機的吧,無序的吧)

如果某個線程在使用完臨界段方法後,其他早先等待的線程都可以結束等待,一起重新競爭CPU(競爭到對象鎖,就獲得CPU時間片,可以說一起競爭CPU,也沒錯),則可以使用notifyAll()方法。

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