先回答問題:
(1)為什麼wait()必須在同步(synchronized)方法/**塊中呼叫?
答:呼叫wait()就是釋放鎖,釋放鎖的前提是必須要先獲得鎖,先獲得鎖才能釋放鎖。
(2)為什麼notify(),notifyall()必須在同步(synchronized)方法/**塊中呼叫?
答:notify(),notifyall()是將鎖交給含有wait()方法的執行緒,讓其繼續執行下去,如果自身沒有鎖,怎麼叫把鎖交給其他執行緒呢;(本質是讓處於入口佇列的執行緒競爭鎖)
下面是正文(詳細解釋):
之前一直謹記老師教的wait(),notify(),notifyall()必須要在synchronized關鍵中使用,不得其解,現在研究了一下,終於明白了。
首先,要明白,每個物件都可以被認為是乙個"監視器monitor",這個監視器由三部分組成(乙個獨佔鎖,乙個入口佇列,乙個等待佇列)。注意是乙個物件只能有乙個獨佔鎖,但是任意執行緒執行緒都可以擁有這個獨佔鎖。
對於物件的非同步方法而言,任意時刻可以有任意個執行緒呼叫該方法。(即普通方法同一時刻可以有多個執行緒呼叫)
對於物件的同步方法而言,只有擁有這個物件的獨佔鎖才能呼叫這個同步方法。如果這個獨佔鎖被其他執行緒占用,那麼另外乙個呼叫該同步方法的執行緒就會處於阻塞狀態,此執行緒進入入口佇列。
若乙個擁有該獨佔鎖的執行緒呼叫該物件同步方法的wait()方法,則該執行緒會釋放獨佔鎖,並加入物件的等待佇列;(為什麼使用wait()?希望某個變數被設定之後再執行,notify()通知變數已經被設定。)
某個執行緒呼叫notify(),notifyall()方法是將等待佇列的執行緒轉移到入口佇列,然後讓他們競爭鎖,所以這個呼叫執行緒本身必須擁有鎖。
synchronized應用舉例:生產者消費者模型
消費者執行緒需要等待直到生產者執行緒完成一次寫入操作。生產者執行緒需要等待消費者執行緒完成一次讀取操作。假設沒有應用synchronized關鍵字,當消費者執行緒執行wait操作的同時,生產線執行緒執行notify,生產者執行緒可能在等待佇列中找不到消費者執行緒。導致消費者執行緒一直處於阻塞狀態。那麼這個模型就要失敗了。所以必須要加synchronized關鍵字。
下面這個圖是執行緒的狀態圖,沒有太大關係,可以不看
先回答問題:
同步 volatile關鍵字
volatile是一種比sychronized關鍵字更輕量級的同步機制 訪問volitile變數時,不會執行加鎖操作 訪問非volitile變數時,每個執行緒會從系統記憶體 主記憶體 拷貝變數到工作記憶體中,然後修改工作記憶體中的變數值,操控的變數可能不同,造成混亂。volatile修飾的變數,是直...
鎖 同步關鍵字 Thread Runnable
即具有相關提供 api,可復用鎖 讀寫鎖等 安卓中需要對執行緒進行暫時休眠時,需要先進行lock 或進行looper 中的message佇列進行等待 loop.prepare loop.loop 在對執行緒或 塊進行以上相關操作時,須對執行緒或 塊進行同步操作 對具體需要執行的 比如wait 或 n...
構造方法與方法的呼叫 this關鍵字
1 方法 package com.wyq.study public class person 建立乙個引數的構造方法 public person string name public person string name,int age public person string name,int a...