C # for lock operations for a particular condition, do not lock, but mutex

Background: Users receive coupons, the same need to lock a user to verify that have been issued, different users can receive simultaneously.

The Code Example:

1, create a Person class

    /// <summary>
    /// Person类
    /// </summary>
    public class Person
    {
        /// <summary>
        /// id
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        ///  姓名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 是否获得优惠券
        /// </summary>
        public bool IsGetCoupon { get; set; }
    }

2.1 The method is an unlocked (can occur in case of receiving repeated)

        ///  <Summary> 
        /// Get a coupon
         ///  </ Summary> 
        public  static  void GetCoupon (the Person Person) 
        { 
            Console.WriteLine ( " DATE: {0: the MM-dd-YYYY HH: mm: SS}, name: {1}, come to receive coupons " , DateTime.Now, person.Name); 
            IF (person.IsGetCoupon) 
            { 
                // pretend business process 
                Thread.Sleep ( 1000 ); 
                Console.WriteLine ( " DATE: {0 : yyyy-mM-dd HH: mm: ss}, name: {1}, have been issued, can not be repeated to receive " , the DateTime.Now, person.Name); 
            } 
            the else 
            { 
                //Pretend service processing 
                the Thread.Sleep ( 1000 );
                 // get 
                person.IsGetCoupon = to true ; 
                Console.WriteLine ( " DATE: {0: the MM-dd-YYYY HH: mm: SS}, name: {}. 1, receiving the success " , the DateTime.Now, person.Name); 
            } 
        }

2.2, plus lock lock method, all the people to receive coupons, had to row on the collar (not good)

        ///  <Summary> 
        /// Lock acquisition coupon
         ///  </ Summary> 
        public  static  void LockGetCoupon (the Person Person) 
        { 
            Console.WriteLine ( " DATE: {0: the MM-dd-YYYY HH: mm: SS} , name: {1}, come to receive coupons " , DateTime.Now, person.Name);
             Lock (LockObj) 
            { 
                // if the judge has been receiving 
                iF (person.IsGetCoupon) 
                { 
                    // pretend business process 
                    Thread.Sleep ( 1000 ); 
                    Console.WriteLine ( " DATE: {0: the mM-dd-YYYY HH: mm: SS}, name: {}. 1, has to receive, collect unrepeatable" , The DateTime.Now, person.Name); 
                } 
                the else 
                { 
                    // pretend service processing 
                    the Thread.Sleep ( 1000 );
                     // get 
                    person.IsGetCoupon = to true ; 
                    Console.WriteLine ( " DATE: {0: the MM-dd-YYYY HH: mm: ss}, name : {1}, get success " , the DateTime.Now, person.Name); 
                } 
            } 
        }

2.3, mutex lock, mutex, only the id of the same person, only to receive a row, id different people can receive at the same time

        /// <summary>
        /// Mutex,领取
        /// </summary>
        /// <param name="person"></param>
        public static void MutexGetCoupon(Person person)
        {
            Console.WriteLine("date:{0:yyyy-MM-dd HH:mm:ss},name:{1},前来领取优惠券", DateTime.Now, person.Name);
            using (var mutex = new Mutex(false, person.Id.ToString()))
            {
                try
                {
                    if (mutex.WaitOne(-1, false))
                    {
                         ;// if judged to have been receiving 
                        IF (person.IsGetCoupon) 
                        { 
                            // pretend service processing 
                            the Thread.Sleep ( 1000 ); 
                            Console.WriteLine ( " DATE: {0: the MM-dd-YYYY HH: mm: SS}, name: { 1}, have been issued, can not be repeated to receive " , the DateTime.Now, person.Name); 
                        } 
                        the else 
                        { 

                            // pretend service processing 
                            the Thread.Sleep ( 1000 );
                             // get 
                            person.IsGetCoupon = to true 
                            Console.WriteLine ("date:{0:yyyy-MM-dd HH:mm:ss},name:{1},领取成功", DateTime.Now, person.Name);
                        }
                    }
                }
                catch (Exception ex)
                {
                    //TxtLogHelper.WriteLog(ex);
                }
                finally
                {
                    mutex.ReleaseMutex();
                }
            }
        }
    }

3.1, start the test (unlocked)

        static  void the Main ( String [] args) 
        { 
            // instantiate three 
            the Person P1 = new new the Person {Id = 24 , the Name = " Kobe " }; 
            the Person P2 = new new the Person {Id = 25 , the Name = " Rose " }; 
            P3 the Person = new new the Person {Id = 23 is , the Name = " Lebl " }; 

            // open multithreading, multiple analog three simultaneously initiating a request to receive 
            for ( int I = 0; i < 4; i++)
            {
                new Thread(() =>
                {
                    GetCoupon(p1);
                }).Start();
                new Thread(() =>
                {
                    GetCoupon(p2);
                }).Start();
                new Thread(() =>
                {
                    GetCoupon(p3);
                }).Start();
            }
            Console.ReadLine();
        }

Test results: Everyone receive duplicate

3.2 Test lock lock method,

        private static readonly object LockObj = new object();
        static void Main(string[] args)
        {
            //实例化三个人
            Person p1 = new Person { Id = 24, Name = "Kobe" };
            Person p2 = new Person { Id = 25, Name = "Rose" };
            Person p3 = new Person { Id = 23, Name = "Lebl" }; 

            // open multithreading, multiple analog three simultaneously initiating a request to receive 
            for ( int I = 0 ; I < . 4 ; I ++ ) 
            { 
                new new the Thread (() => 
                { 
                    LockGetCoupon (P1); 
                }). The Start ( ); 
                new new the Thread (() => 
                { 
                    LockGetCoupon (P2); 
                }) the Start ();. 
                new new the Thread (() => 
                { 
                    LockGetCoupon (P3); 
                }) the Start ();. 
            } 
            Console.ReadLine (); 
        }

Test results: While avoiding repetition receive, but everyone's every request row right. If the user is large, then, this way efficiency is too low, it is not recommended.

 3.3 Test mutex lock, mutex

        static void Main(string[] args)
        {
            //实例化三个人
            Person p1 = new Person { Id = 24, Name = "Kobe" };
            Person p2 = new Person { Id = 25, Name = "Rose" };
            Person p3 = new Person { Id = 23, Name = "Lebl" };

            //开启多线程、模拟三个人同时发起多次领取请求
            for (int i = 0; i < 4; i++)
            {
                new Thread(() =>
                {
                    MutexGetCoupon(p1);
                }).Start();
                new Thread(() =>
                {
                    MutexGetCoupon(p2);
                }).Start();
                new Thread(() =>
                {
                    MutexGetCoupon(p3);
                }).Start();
            }
            Console.ReadLine();
        }

测试结果:既避免了重复领取,也避免了堵塞用户请求的情况。见下面截图,Kobe、Rose、Lebl是同时领取的优惠券,但是每个人的重复请求都在排对

总结:mutex锁,完美的解决了此类问题。

 

Guess you like

Origin www.cnblogs.com/bookobe/p/11229021.html