使用線程的一個重要方面是同步通路多個線程通路的任何變量。
背景:當多個線程共享資料,其中一個或多個線程要修改資料時,有可能引起資料不統一等問題。
同步:是指在某一時刻隻有一個線程可以通路某共享資料
1、同步的含義
同步問題的産生,主要是由于在進階語言的源代碼中,大多數情況下看起來是一條語句,但在最後編譯好的彙編語言機器碼中則會被翻譯為許多條語句,進而在作業系統排程時被劃分到不同的時間片中。
例如:
message += "Hello world!";
這條語句在C#文法上是一條語句,但在執行代碼時,實際上它涉及到許多操作。需要重新配置設定記憶體以存儲更長的新字元串,需要設定變量message使之指向新的記憶體,需要複制實際文本等。
2、在C#中處理同步
通過對指定對象的加鎖和解鎖可以實作同步代碼段的通路。
在.NET的System.Threading命名空間中提供了Monitor類來實作加鎖與解鎖。該類中的方法都是靜态的。如下表:
C#中 lock關鍵字提供了與Monitoy.Enter和Monitoy.Exit同樣的功能,這種方法用在你的代碼段不能被其他獨立的線程中斷的情況。通過對Monitor類的簡易封裝,lock為同步通路變量提供了一個非常簡單的方式,其用法如下:
lock(x)
{
// 使用x的語句
}
lock語句把變量放在圓括号中,以包裝對象,稱為獨占鎖或排它鎖。當執行帶有lock關鍵字的複合語句時,獨占鎖會保留下來。當變量被包裝在獨占鎖中時,其他線程就不能通路該變量。如果在上面的代碼中使用獨占鎖,在執行複合語句時,這個線程就會失去其時間片。如果下一個獲得時間片的線程試圖通路變量,就會被拒絕。Windows會讓其他線程處于睡眠狀态,直到解除了獨占鎖為止。
3、同步時要注意的問題
線程同步非常重要,但隻在需要時使用也是非常重要的。因為這會降低性能。原因有兩個:
首先,在對象上放置和解開鎖會帶來某些系統開銷,但這些系統開銷都非常小。第二個原因更為重要,線程同步使用得越多,等待釋放對象的線程就越多。如果一個線程在對象上放置了一個鎖,需要通路該對象的其他線程就隻能暫停執行,直到該鎖被解開,才能繼續執行。是以,在lock塊内部編寫的代碼越少越好,以免出現線程同步錯誤。lock語句在某種意義上就是臨時禁用應用程式的多線程功能,也就臨時删除了多線程的各種優勢。
本文轉自terryli51CTO部落格,原文連結: http://blog.51cto.com/terryli/520675,如需轉載請自行聯系原作者