2016-09-06 40 views
0

我有兩種方法,第一()和第二(),我將它們分配給兩個線程。與Monitor.Pulse線程同步NOT按預期工作

以下是我的第二和第一方法

 public void first() 
    { 
     lock (this) 
     { 
      Monitor.Wait(this); 

      Console.WriteLine("First"); 
      Monitor.Pulse(this); 
     } 
    } 

    public void second() 
    { 
     lock (this) 
     { 
      //Monitor.Wait(this); 
      Console.WriteLine("Second"); 
      Monitor.Pulse(this); 
     } 
    } 

的問題是在控制檯上只有「二」是越來越打印。 儘管我在第二個()中有Monitor.Pulse()來通知控件應該轉移到first(),但是不會發生。

我下面的MSDN以下https://msdn.microsoft.com/en-us/library/aa645740(v=vs.71).aspx

任何幫助可以理解爲信息爲什麼s線程不是轉向控制f線程與第二Monitor.Pulse()()

Follwinng是我的主要()

 test t = new test(); 
     test1 t1 = new test1(); 
     Thread f = new Thread(new ThreadStart(t.first)); 
     Thread s = new Thread(new ThreadStart(t1.second)); 
     f.Start(); 
     s.Start(); 
     f.Join(); 
     s.Join(); 

回答

4

生產者/消費者示例適用於單元格的一個實例。我認爲你應該這樣做。對'this'的引用對於'第一'和'第二'是不同的。

+2

即使這個問題得到解決,這裏仍然有一場比賽,'second'假定'first'獲得了鎖,並且在'second'獲得鎖之前進入了'Wait'。 (因爲'沒有任何人的脈搏'等待'丟棄) –

+0

@Damien_The_Unbeliever但是這個答案工作正常。 – Alex

+1

@Alex - 它會 - *一些*的時間。這是一場比賽,看看哪個線程實際上首先執行'lock(this)'行,而不是*保證*。 –

1

既然你初始化Test -class的兩個實例(或者你有兩個獨立的類,TestTest1),你在這兩種方法中this -keyword的使用是指兩個不同的對象。

而不是鎖定在上下文對象上的,創建一個靜態對象,對兩種方法訪問,並就鎖:

public class Test 
{ 
    static object _key = new object(); 

    public void First() 
    { 
     lock (_key) 
     { 
      Monitor.Wait(_key); 
      Console.WriteLine("First"); 
      Monitor.Pulse(_key); 
     } 
    } 

    public void Second() 
    { 
     lock (_key) 
     { 
      Console.WriteLine("Second"); 
      Monitor.Pulse(_key); 
     } 
    } 
} 

放入同一個類都First()Second(),創造的這兩個實例類,而不是一個Test和一個Test1,你應該看到預期的結果,即程序的輸出將是

Second 
First 

編輯:由於Damien points out though,這也不能保證可以工作,因爲它假定First()是第一個獲得鎖定的。

+0

如果'First'實際上是*第一個成功獲取'lock'的方法,那麼您將只能看到該輸出,當您剝離兩個線程來執行這些方法時,這絕對不能保證。 –