簡體   English   中英

使用'this'與另一個對象鎖定同步塊中的wait和notify

[英]Using 'this' versus another object as lock in synchronized block with wait and notify

我有兩個代碼塊,一個等待另一個通知它。

synchronized(this) {
    wait();
}

while(condition) {
    //do stuff
    synchronized(this) {
        notify();
    }
}

奇怪的是,在這樣做時沒有等待通知:

synchronized(objectLock) {
    objectLock.wait();
}

while(condition) {
    //do stuff
    synchronized(objectLock) {
        objectLock.notify();
    }
}

我對這兩組的差異非常好奇,為什么第一組有效,而另一組沒有。 請注意,這兩個塊位於兩個不同方法的兩個不同線程中(如果這有幫助)。

我希望有人可以解釋為什么會這樣。 我編輯了我的問題所以它會更加詳細。

您可以使用任何您喜歡的對象。 但是,其他程序員通常更清楚地看到顯式鎖對象。

我的胡亂猜測,為什么this不適合你的工作是你有不同的this范圍。 (即,在匿名函數/回調中)。 您可以通過附加類名來明確說明要使用哪個類,例如, WonderClass.this - this也是為什么this不清楚的原因。 (編輯:實際上是WhateverClass.this如果this真的是一個不同的實例, this對你沒有幫助)

另請閱讀: http//docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html - 我通常會發現將所有線程不安全的代碼放入小型同步方法(執行隱含鎖定)更容易在此)

它沒有工作,因為你在同步this這兩個不同的線程指出,兩個不同的 Thread對象。

wait()notify()同步只有在同一個對象上進行同步鎖定時才能正常工作,就像稍后使用的objectLock一樣。

編輯:如果兩個線程實例屬於同一個MyThread類,那么為了達到您認為代碼所具有的效果,您必須獲取其類對象本身的鎖定:

synchronized(MyThread.class)

當你說這兩個塊存在於兩個不同的線程中時,我認為它們並沒有鎖定在同一個對象上,因為this不是一回事。 當您命名一個顯式鎖定時,您使用相同的東西來鎖定。

順便說一下,你應該在循環中調用wait ,如下所示:

synchronized(someLock) {
   while (!someCondition) {
       wait();
   }
   // now the thread has the lock and it can do things 
   // knowing for sure that someCondition is true
}

如果沒有這個,您將容易受到虛假喚醒的攻擊(並非所有通知都來自您的應用程序代碼),並且調用waitnotify的順序會出現問題(如果您有兩個線程,並且在另一個等待之前通知,那么通知永遠不會被看到)。

無論如何,我建議使用Monitor模式( http://en.wikipedia.org/wiki/Monitor_(synchronization) ),這可以避免以后的錯誤,特別是當您的用例變得更復雜時:

class Monitor
{
    /** Initialised to `false` by default in Java. */
    boolean condition;

    synchronized void waitForSomething()
    {
        while(!condition)
        {
            wait();
        }
    }

    synchronized void signal()
    {
        condition = true;

        notify();
    }
}

這樣一切都很好地封裝和保護(我通常不會在示例中使用private修飾符,但您可能希望在代碼中強制執行額外的“隱私”,特別是將condition private 。)

正如你所看到的,在我的條件循環中有wait()調用,而不是你在循環中有notify()例子。 在大多數用例中,使用notify做的事情是錯誤的,雖然我不能代表您的具體情況,因為您沒有向我們提供足夠的詳細信息。 我願意打賭你的是典型的,其中Monitor模式適用得很漂亮。

使用場景如下:想要等待某事的線程調用waitForSomething而另一個線程可能通過調用將設置條件標志的signal方法使其繼續。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM