lock是什麼. 1 public class ThreadTest 2 { 3 private int i = 0; 4 public void Test() 5 { 6 Thread t1 = new Thread(Thread1); 7 Thread t2 = new Thread(Thread2); 8 t1.Start(); 9 t2.Start(); 10 } 11 public void Thread1() 12 { 13 lock (this) 14 { 15 Console.WriteLine(this.i); 16 Thread.Sleep(1000); 17 Console.WriteLine(this.i); 18 } 19 } 20 public void Thread2() 21 { 22 Thread.Sleep(500); 23 this.i = 1; 24 Console.WriteLine("Change the value in locking"); 25 } 26 } 27 public class ThreadTest2 28 { 29 private int i = 0; 30 public void Test() 31 { 32 Thread t1 = new Thread(Thread1); 33 Thread t2 = new Thread(Thread2); 34 t1.Start(); 35 t2.Start(); 36 } 37 public void Thread1() 38 { 39 lock (this) 40 { 41 Console.WriteLine(this.i); 42 Thread.Sleep(1000); 43 Console.WriteLine(this.i); 44 } 45 } 46 public void Thread2() 47 { 48 lock (this) 49 { 50 Thread.Sleep(500); 51 this.i = 1; 52 Console.WriteLine("Can't change the value in locking"); 53 } 54 } 55 } 兩段程式有什麼區別嗎?看看吧,ThreadTest2.Thread2()中多了一個lock(this)卻產生了不同的結果 本想在案例一中lock住this對象,讓其他的線程不能操作,可是事情不是像我們想象的那樣lock(this)是lock this的意思.this中的屬性依然能夠被別的線程改變.那我們lock住的是什麼?是程式碼片段,是lock後面大括弧中程式碼片段,這段代碼讓多個人執行不不被允許的.那返回頭來在看lock(this),this是什麼意思呢?可以說this知識這段代碼域的標誌,看看案例二中Thread2.Thread2就明白了,Thread2中的lock需要等到Thread1種lock釋放後才開始運行,釋放之前一直處於等待狀態,這就是標誌的表現. 好吧,讓我們來瞭解一下,lock這段代碼是怎麼啟動並執行.lock語句根本使用的就是Monitor.Enter和Monitor.Exit,也就是說lock(this)時執行Monitor.Enter(this),大括弧結束時執行Monitor.Exit(this).他的意義在於什麼呢,對於任何一個對象來說,他在記憶體中的第一部分放置的是所有方法的地址,第二部分放著一個索引,他指向CLR中的SyncBlock Cache地區中的一個SyncBlock.什麼意思呢?就是說,當你執行Monitor.Enter(Object)時,如果object的索引值為負數,就從SyncBlock Cache中選區一個SyncBlock,將其地址放在object的索引中。這樣就完成了以object為標誌的鎖定,其他的線程想再次進行Monitor.Enter(object)操作,將獲得object為正數的索引,然後就等待。直到索引變為負數,即線程使用Monitor.Exit(object)將索引變為負數。 如果明白了Monitor.Enter的原理,lock當然不再話下.當然lock後括弧裡面的值不是說把整個對象鎖住,而是對他的一個值進行了修改,使別的lock不能鎖住他,這才是lock(object)的真面目. 但在實際使用中Monitor還是不推薦,還是lock好的,Monitor需要加上很多try catch才能保證安全性,但lock卻幫我們做了,而且lock看起來更優雅. 在靜態方法中如何使用lock呢,由於我們沒有this可用,所以我們使用typeof(this)好了,Type也有相應的方法地址和索引,所以他也是可以來當作lock的標誌的. 但微軟不提倡是用public的object或者typeof()或者字串這樣的標誌就是因為,如果你的public object在其他的線程中被null並被垃圾收集了,將發生不可預期的錯誤. 轉:http://blog.whjs.gov.cn/user1/burningsnow/archives/2007/20072102051.html |