使用鎖解決執行緒爭用的問題

2022-07-14 08:39:21 字數 2624 閱讀 6105

最近一直在學習c#的多執行緒程式設計,發現多執行緒程式設計並不容易。在啟動訪問相同資料的多個執行緒時,會間歇性地遇到難以發現的問題。下面來討論與執行緒相關的問題:爭用條件。如果兩個或多個執行緒訪問相同的物件,或者訪問不同步的共享狀態,就會出現爭用條件。看下面的例子:

using system;

2:

using system.collections.generic;

3:

using system.linq;

4:

using system.text;

5:

using system.diagnostics;

6:

using system.threading;

7:

using system.threading.tasks;

8:
9:

namespace threadingissues

10:
26:             state = 5;
27:         }
28:     }
29:
30:

//建立乙個分配給任務的乙個方法

31:

public

class sampletask

32:
43:         }
44:     }
45:
46:

class program

47:
55:            thread.sleep(10000);
56:        }
57:    }
58: }
59:
60:
61:
執行這個示例的結果:

在執行到63414個迴圈時,出現爭用條件的程式斷言。多次啟動應用程式,總會得到不同的結果。要避免這個問題,可以鎖定共享的物件。這個過程通過在使用共享物件的方法中進行鎖定以及將共享物件設定為執行緒安全的物件來實現。

**如下:

using system;

2:

using system.collections.generic;

3:

using system.linq;

4:

using system.text;

5:

using system.diagnostics;

6:

using system.threading;

7:

using system.threading.tasks;

8:
9:

namespace threadingissues

10:
28:             }
29:             state = 5;
30:         }
31:     }
32:
33:

//建立乙個分配給任務的乙個方法

34:

public

class sampletask

35:
48:             }
49:         }
50:     }
51:
52:

class program

53:
61:             thread.sleep(10000);
62:         }
63:     }
64: }
執行結果如下:

總結:使用lock語句鎖定共享state物件的**塊,只有乙個執行緒能在鎖定塊中處理共享的state物件。由於這個物件在所有的執行緒之前共享,因此如果乙個執行緒鎖定了state物件,另外乙個執行緒必須等待該鎖定的解除。一旦接收鎖定,該執行緒就擁有該鎖定,直到該鎖定塊的末尾才解除鎖定。如果改變state變數引用的物件的每個執行緒都使用乙個鎖定,就不會出現爭用條件。

在將共享物件state設定為執行緒安全的物件時,由於stateobject類內部的變數state(注意這個state變數和前面的state物件不是同乙個)是int型別,由於lock不能鎖定值型別本身(只有引用型別才能用於鎖定),因此需要定義乙個object型別的變數sync,將它用於lock語句。如果每次state的值更改時,都使用同步物件來鎖定,就不會出現爭用條件.

多執行緒 互斥鎖解決買票問題

在這個 介紹了多執行緒的安全隱患 買票問題 總票數 property nonatomic,assign int tickets end void touchesbegan nsset touches withevent uievent event 加鎖,互斥鎖 加鎖,鎖定的 盡量少 加鎖範圍內的 同...

用互斥鎖解決讀者 寫者問題

include include 讀 寫的次數限制,防止程式無限制的執行 define max time 12 void read void pread void write void pwrite void init time char buffer 確定緩衝區中是否有資料 int buffer h...

多執行緒鎖的問題

public class synctest start new thread new runnable start class a catch interruptedexception e system.out.println i public void f2 catch interruptedex...