2012-07-04 104 views
0

在Java中,你可以等待每個對象,所以這種情況是可能的方案:在對象C#等待和脈衝

線程A等待的對象

線程B等待b

關於b A

線程A分配時通知線程C-分配時通知

如果我使用C#的監控,在我看來,該線程C可才醒悟b向上(或b和A),然後怎麼辦我是個可能有這種情況嗎?

+1

通常你會從代碼開始...... –

+0

當它的抽象,至少在我看來,這個問題是更可讀的方式 –

+0

什麼是等效的Java代碼? – SLaks

回答

1

你似乎認爲,因爲C#同步功能是Monitor類的成員,你需要一個特殊的Monitor實例使用它們,而相比之下,Java的,他們是java.lang.Object類的成員,並適用於所有對象。

恰恰相反。根本沒有Monitor實例。在C#中,這些函數是靜態方法,並且仍然適用於任何對象。 Monitor類的唯一原因是爲了防止System.Object與額外的成員混淆(這將顯示在Intellisense建議列表中,等等)。

但是,我發現代碼使用Pulse通常有隱藏的競爭條件。有更好的方法可以讓線程之間進行同步,使編寫可靠的代碼變得更容易。

+0

是的,那正是我想的......謝謝! –

1

您正在查找的Monitor.WaitMonitor.Pulse方法。

3

如果我使用C#的監控,在我看來,該線程C可才醒悟b了

爲什麼?它的線程C調用Monitor.Pulse(a),那麼它將喚醒線程A,就像在Java中使用a.pulse()一樣。

雖然有一些細微的差別,在Monitor.Wait .NET/Pulse/PulseAll非常類似於Java Object.wait/notify/notifyAll。我強烈懷疑,你現在想的不是這種情況,但沒有具體的代碼很難說。

+0

你是對的,我沒有注意到方法給了一個對象作爲參數等待。 –

+1

@OfekRon:值得注意的是,如果你試圖想出一個完整的問題示例,你會很快遇到過這樣的問題:) –

0

我不確定我是否正確理解了你,但我沒有看到任何問題。下面的代碼被有意簡化,沒有爲a和b的類和沒有聲明:

public void ThreadARunner() 
{ 
    lock(a) 
     Monitor.Wait(a); //waits here until thread C pulses, releasing the lock on a 
    lock(b) 
     Monitor.Pulse(b); //wakes up thread B 
} 

public void ThreadBRunner() 
{ 
    lock(b) 
     Monitor.Wait(b); //waits here until thread A pulses, releasing the lock on b 
} 

public void ThreadCRunner() 
{ 
    lock(a) 
     Monitor.Pulse(a); //wakes up thread a 
} 

對於進一步的幫助,提供更多的細節。 閱讀here瞭解Monitor如何在C#中工作。

+0

@Ben Care解釋一下? – Fengari