Research on multi-thread Synchronous Lock (Lock) in c # And cross-thread UI operations,
This article only focuses on the lock used by multi-thread synchronization in C. To display the results more intuitively, you can write out the code for multi-threaded UI operations through the event during the demo.
In fact, multi-thread synchronization has been used many times using the Synchronous lock method. Today, I accidentally see the following in MSDN:
1 private static readonly object locker1 = new object();2 private readonly object locker2 = new object();
Note: The original text does not include readonly, but I added it myself later.
I thought about their differences.
Then I wrote a piece of code for testing. The test class code is as follows:
/// <Summary> /// parameters passed when the UI is operated across threads. This article aims to display messages, therefore, a simple encapsulation of // </summary> public class MyEventArgs: EventArgs {public readonly string Message = string. empty; public MyEventArgs (string msg) {this. message = msg ;}/// <summary> // test class, used to test the differences between the two locks // </summary> public class LockTest {// two locks private static readonly object Locker1 = new object (); private readonly object Locker2 = new object (); // <sum Mary> // delegate and event for cross-thread UI operations /// </summary> public delegate void MessageEventHandler (object sender, MyEventArgs e); public event MessageEventHandler MessageEvent; public void OnMessage (MyEventArgs e) {if (this. messageEvent! = Null) MessageEvent (this, e);} // The variable to be locked. The effect of the two locks is private int num = 0 in different cases; // Instance Name private readonly string name; public LockTest (string Name) {name = Name;} // Method for executing the first lock public void AddNum1 () {lock (Locker1) {num = 0; ShowMessage () ;}// public void AddNum2 () {lock (Locker2) {num = 0; ShowMessage ();}} // lock some operations and display key messages to private void ShowMessage () {string msg = "" In the UI of the main thread through events ""; for (int I = 0; I <10; I ++) {num + = 1; msg = string. format ("Thread [{0}], the num value in instance [{1}] is [{2}]", Thread. currentThread. name, this. name, num); OnMessage (new MyEventArgs (msg); Thread. sleep (100);} msg = string. format ("====== Thread [{0}] execution completed ======", Thread. currentThread. name); OnMessage (new MyEventArgs (msg ));}}
After the test class is completed, start the test:
First, test the differences between two locks for a single instance and multiple threads:
private void button1_Click(object sender, EventArgs e) { LockTest test = new LockTest("LockTest 1"); test.MessageEvent += new LockTest.MessageEventHandler(MessageCallBack); listBox1.Items.Clear(); for (int i = 0; i <= 2; i++) { Thread a = new Thread(new ThreadStart(test.AddNum1)); a.Name = i.ToString(); a.Start(); } } private void button2_Click(object sender, EventArgs e) { LockTest test = new LockTest("LockTest 1"); test.MessageEvent += new LockTest.MessageEventHandler(MessageCallBack); listBox1.Items.Clear(); for (int i = 0; i <= 2; i++) { Thread a = new Thread(new ThreadStart(test.AddNum2)); a.Name = i.ToString(); a.Start(); } }
The output results are exactly the same:
It is concluded that there is no difference between the two locks when multiple threads access an instance.
The following describes how to test multiple instances (static locks ):
private void button3_Click(object sender, EventArgs e) { listBox1.Items.Clear(); for (int i = 0; i <= 2; i++) { LockTest test = new LockTest("LockTest " + i.ToString()); test.MessageEvent += new LockTest.MessageEventHandler(MessageCallBack); Thread a = new Thread(new ThreadStart(test.AddNum1)); a.Name = i.ToString(); a.Start(); } }
Expected result:
It is concluded that in the face of static locks, the thread still needs to queue. Although it is not an instance, the lock is unique and the thread only recognizes the lock, so the thread has no concurrency!
Continue test (non-static lock ):
private void button4_Click(object sender, EventArgs e) { listBox1.Items.Clear(); for (int i = 0; i <= 2; i++) { LockTest test = new LockTest("LockTest " + i.ToString()); test.MessageEvent += new LockTest.MessageEventHandler(MessageCallBack); Thread a = new Thread(new ThreadStart(test.AddNum2)); a.Name = i.ToString(); a.Start(); } }
Result:
It is concluded that when the non-static lock is used, multiple threads are concurrent and work together.
In fact, the test results can be guessed before. However, if you don't test the results, you will always feel that the test is complete!
Form, used for Event Callback, the code displayed in the UI is here:
delegate void MessageHandler(string msg); public void MessageCallBack(object sender, MyEventArgs e) { MessageHandler handler = new MessageHandler(ShowMessage); this.Invoke(handler, new object[] { e.Message }); } public void ShowMessage(string msg) { this.listBox1.Items.Add(msg); }