[英]Java sync games: synchronized && wait && notify
我來自.NET
世界,不幸的是用.NET
的眼睛看Java源代碼。
以下代碼來自Android應用程序(雖然根本不是Android特定的):
private class Worker implements Runnable {
private final Object mLock = new Object();
private Looper mLooper;
Worker(String name) {
Thread t = new Thread(null, this, name);
t.start();
synchronized (mLock) {
while (mLooper == null) {
try {
mLock.wait();
} catch (InterruptedException ex) {
}
}
}
}
public Looper getLooper() {
return mLooper;
}
public void run() {
synchronized (mLock) {
Looper.prepare();
mLooper = Looper.myLooper();
mLock.notifyAll();
}
Looper.loop();
}
public void quit() {
mLooper.quit();
}
}
我不清楚synchronized
工作原理。 首先我認為synchronized是鎖定mLock對象,但是如果在t.start()
構造函數線程首先進入同步塊之后,它將在mLock.wait()
阻止它,並通過阻止它進入synchronized來隱式阻止線程“t”塊。
這顯然是錯誤的,因為我的電話按照假設:)
接下來想到同步同步“代碼塊”(在這種情況下,兩個同步塊是獨立的=>線程可以同時無限制地輸入兩個不同的同步塊),並且完全適合...
...直到我的同事告訴我mLock.wait()
釋放鎖定mLock並允許其他線程同時進入mLock的關鍵部分。
我不確定我是否足夠清楚,所以很樂意回答任何進一步的問題。
查看Object.wait()上的javadoc。 這是“神奇的”,因為它會丟棄進入synchronized {}塊時獲取的監視器。 這允許另一個線程獲取監視器並調用Object.notify() 。
當另一個線程調用notify()從wait()調用中喚醒等待線程時,等待線程必須重新獲取監視器並將阻塞直到它可以 - 監視器僅在wait()調用期間被丟棄。 並且通知線程在新喚醒的等待線程可以繼續之前完成其同步塊。 一切都按可預測順序排列。
synchronized
使用對象監視器。 在對象上調用wait()
以原子方式釋放對象監視器(否則沒有其他線程可以占用監視器並向服務員發出notify
)。
是。 如果您閱讀了wait()
方法的描述,您將了解到它導致線程釋放鎖並阻塞,直到另一個線程在鎖上調用notify
或notifyAll
。 當前線程等待它可以重新獲取鎖定,一旦它執行,它將繼續執行。
所示的代碼如下實踐差,但是,因為它“發布”(即,它使其他線程訪問的對象)的Worker
實例被完全構造之前。 在這種方法中使用額外的障礙,結合階級的private
性質,可能會使這種情況安全,但總的來說,事實並非如此。
讓我解釋:
構造函數啟動一個將執行run()方法的新線程。 這個新線程將獲得一個新的Looper對象,將其存儲在mLooper字段中,然后運行Looper消息循環。 在它之間它將通知()第一個已設置mLooper的線程。
因此,第一個線程只有在設置了mLooper之后才會從構造函數返回,這意味着第二個線程的Looper.loop()處理很快就會開始/已經開始。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.