2016-04-21 71 views
-1

我不清楚CLR在運行程序時執行的過程。我不清楚何時使用lock()或其他類型的線程安全對象。瞭解多線程和執行過程

請幫我瞭解以下內容:

有了這個代碼:

public class Person { 
     string Name {get;set;} 
    } 


public class Calc { 
    public string DoStuff(Person p){ 
     // perform some processing on person object 
     // maybe call external API and update person object 
    } 

} 

請糾正我,如果我錯了,但是這是我的例1的理解在單線程應用程序(假設它是一個mvc應用程序,我正在使用DI並且已經在容器中註冊了「服務」

我在我的應用程序的某個地方調用了Service.Work(),新的Calc()被創建(CLR在內存中分配這個對象)和Calc.DoStuff()在Person obj上進行計算等。由於在調用新的Calc()之前創建並從兩個瀏覽器中調用它們,它們位於不同的執行路徑中。它是否正確?

// Example 1 
public class Service { 
    public void Work(person) { 
     var calc = new Calc(); 
     string test = calc.DoStuff(person); 
    } 
} 

// Example 2 
public class Service { 
    public Service() { 
     var calc = new Calc(); // this is different 
    } 
    public void Work(person) { 
     string test = calc.DoStuff(person); 
    } 
} 

現在什麼在內存分配計算器服務的時間相同的情況下發生的,但是這次是在服務的構造函數實例化。這會導致同時調用Work()的問題(因爲只有一個Calc對象的實例)

  • 然後會發生什麼?字符串名稱是否填充了「最新」字符串?)。
  • 這裏需要鎖定,所以首先它必須完成第一個呼叫請求然後第二個?
  • 當兩個瀏覽器調用Work(Person)向該方法發送Person的兩個實例時會發生什麼。假設Person對象出現在Calc類的「內部」,然後調用一個外部API,並停頓一段時間。然後第二個請求被調用到Calc(Person)這個Person對象是否會獨立更新(即使Calc()只有一個實例?)。或者第一個請求(被停止的請求)被第二個被取消而被遺忘?
+0

「所以,如果兩個瀏覽器執行Calc.DoStuff()...」 - 您提到了瀏覽器。這是一個ASP.NET應用程序嗎? – mbeckish

+0

是和否 - 因爲它可能是瀏覽器,但它可能是應用程序的兩個不同組件同時調用Service.Work()。這有什麼區別嗎?如果它是Asp.net或不是? – BobSwanson

回答

0

這裏就是你的直覺去錯了:

現在是什麼的時候分配服務在內存Calc是在服務的 構造函數實例的 在相同的情況下發生的,但是這一次。但願事業問題,以同時呼叫到 工作()(因爲計算器?對象的只有一個實例。

的服務功能,每次調用都有自己的線程棧,以及所有地方的這樣單獨的副本變量。

對於所有意圖和目的,只是想象這兩個瀏覽器的請求爲兩個完全獨立的程序。

+0

我以爲只有一個線程堆棧?這同樣適用於控制檯應用程序。假設您同時從控制檯應用程序的兩個「區域」調用服務 – BobSwanson

+0

否。這兩個瀏覽器請求由Web服務器中的單獨線程同時處理。 – mbeckish

+0

在控制檯應用程序中,您默認只有一個線程,因此一次只能有一個服務調用發生。如果您創建了兩個線程,要同時調用Service,則每個線程都有自己的堆棧。 – mbeckish

0

一般來說,在這兩種情況下,你不應該指望計算器的該實例是單身(單身),所以你DoStuff方法需要某種類型的同步,例如lock(p),例如,我f類的Person實例對於所有調用都是相同的。