C #, use the Monitor class, Lock and Mutex classes to synchronize multiple threads of execution

In a multi-threaded, in order to maintain the consistency of data must be a function of the data or access data locked in the database that is very common, but because most of them are single-threaded program, so there is no increase in the program lock necessary, but in a multi-threaded, in order to keep pace, be sure to lock the data, but fortunately Framework provides three mechanisms have been locked for us, namely, the Monitor class, lock key and Mutex classes.
        Lock Key words usage of which is relatively simple, Monitor Lock class and usage of the same. Both are locked data or locking function is called. The Mutex is more synchronous calls between multiple threads for locking. Simply put, Monitor and Lock lock is used for calling end, and the multi-use locking calls Mutex end.
For example the following program: Since this program is millisecond, so run the following program may have on different machines in different results on the same machine running at different times have different results, my test environment for vs2005, windowsXp, CPU3.0, 1 G monery.
        There are two program threads thread1, thread2 and a TestFunc function, TestFunc will print out the calling thread name and time (mm-class) call, two threads to 30mm and 100mm respectively TestFunc to call this function. TestFunc execution time is 50mm. Procedure is as follows:
the using the System;
the using the System.Collections.Generic;
the using the System.Text;
the using the System.Threading;
namespace MonitorLockMutex
{
    class Program
    {
        #region variable
        Thread thread1 = null;
        Thread thread2 = null;
        Mutex mutex = null;
        #endregion
        static void Main(string[] args)
        {
            Program p = new Program();
            p.RunThread();
            Console.ReadLine();
        }
        public Program()
        {
            mutex = new Mutex();
            thread1 = new Thread(new ThreadStart(thread1Func));
            thread2 = new Thread(new ThreadStart(thread2Func));
        }
        public void RunThread()
        {
            thread1.Start();
            thread2.Start();
        }
        private void thread1Func()
        {
            for (int count = 0; count < 10; count++)
            {
                TestFunc("Thread1 have run " + count.ToString() + " times");
                Thread.Sleep(30);
            }
        }
        private void thread2Func()
        {
            for (int count = 0; count < 10; count++)
            {
                TestFunc("Thread2 have run " + count.ToString() + " times");
                Thread.Sleep(100);
            }
        }
        Private void TestFunc (String STR)
        {
            Console.WriteLine ( "{{0}}. 1", STR, System.DateTime.Now.Millisecond.ToString ());
            the Thread.Sleep (50);
        }
    }
}
Run Results as follows:
        As can be seen, then, if not locked, the two threads are substantially in accordance with the respective time interval + TestFunc the execution time (50mm) TestFunc function for reading. Because the thread needs to allocate memory at the beginning, so the 0th call inaccurate, it can be seen from the first call 1 to 9 times, thread1 execution interval is about 80mm, the execution interval thread2 is about 150mm.
TestFunc now be modified as follows:
Private void TestFunc (String STR)
{
   Lock (the this)
   {
      Console.WriteLine ( "{{0}}. 1", STR, System.DateTime.Now.Millisecond.ToString ());
      the Thread.Sleep (50);
   }
}
or a Monitor is the same, as follows:
Private void TestFunc (String STR)
{
      the Monitor.Enter (the this);
      Console.WriteLine ( "{{0}}. 1", STR, System.DateTime. Now.Millisecond.ToString ());
      the Thread.Sleep (50);
      the Monitor.Exit (the this);
}
Enter and Exit Monitor which are static methods.
Lock operation results are as follows:
        Let us analyze the results, the same starting times first. Call time interval between the threads of the same thread execution time + TestFunc call time, call time interval between different threads calling time TestFunc. For example: the time between two consecutive calls thread1 interval is about 30 + 50 = 80; continuous time interval between two calls thread2 about 100 + 50 = 150mm. Call time interval between thread1 and thread2 to 50mm. Because after TestFunc been living lock, so a thread calls TestFunc, when other threads also calls TestFunc, then is discharged into the thread that is waiting in the queue to wait until the release of the thread has access to this resource so far.
        This is the locking feature of the called function, which can only ensure that each is a thread calls, the number of high-priority thread calls the more low is small, this is the so-called preemptive.
        Let us look to use the Mutex class, and the difference between the Monitor and Lock.
The code is modified as follows:
        Private void thread1Func ()
        {
            for (int COUNT = 0; COUNT <10; COUNT ++)
            {
                mutex.WaitOne ();
                TestFunc ( "Thread1 have have RUN" count.ToString + () + "Times");
                mutex.ReleaseMutex ();
            }
        }

        private void thread2Func()
        {
            for (int count = 0; count < 10; count++)
            {
                mutex.WaitOne();
                TestFunc("Thread2 have run " + count.ToString() + " times");
                mutex.ReleaseMutex();
            }
        }

        private void TestFunc(string str)
        {
            Console.WriteLine("{0} {1}", str, System.DateTime.Now.Millisecond.ToString());
            Thread.Sleep(50);
        }
运行结果如下:
        As can be seen, Mutex mutex can only call between threads, but not mutually exclusive repeated calls to this thread, that thread1 in waitOne () only play a mutually exclusive role waitOne thread2 in (), but not by thread1 affect the wainOne () may be called multiple times, but the same number of calls ReleaseMutex at the end of the call () on it.
        So how to make threads are executed in the order of call it? In fact, the combination lock and Mutex used on it, change the code as follows:
        Private void thread1Func ()
        {
            for (int COUNT = 0; COUNT <10; COUNT ++)
            {
                lock (the this)
                {
                    mutex.WaitOne ();
                    TestFunc ( " RUN have have thread1 "count.ToString + () +" Times ");
                    mutex.ReleaseMutex ();
                }
            }
        }

        Private void thread2Func ()
        {
            for (int count = 0; count < 10; count++)
            {
                lock (this)
                {
                    mutex.WaitOne();
                    TestFunc("Thread2 have run " + count.ToString() + " times");
                    mutex.ReleaseMutex();
                }
            }
        }

Reproduced in: https: //www.cnblogs.com/zhangchenliang/archive/2012/04/18/2454761.html

Guess you like

Origin blog.csdn.net/weixin_33964094/article/details/93494900