--- lock key multi-threaded programming learning series

concept

Get lock statement mutex lock a given object, execute statement block, and then release the lock. While holding a lock, holding lock threads can get again and release lock. Prevent any other thread to obtain lock and wait for the release lock.
lock applies only single cases, distributed and balanced debt can be considered a distributed lock.

form
  1. lock(this)
  2. lock(string)
  3. lock(object)
  4. lock(staticObject)
Test code:
class Program
{
     const string firstOrderId = "001";
     const string secondOrderId = "002";
     const string thirdOrderId = "003";

     static void Main()
     {
         test(LockType.LockThis);
         //test(LockType.LockString);
         //test(LockType.LockObject);
         //test(LockType.LockStaticObject);

         Console.ReadLine();
     }

     static void test(LockType lockType)
     {
         Console.ForegroundColor = ConsoleColor.Yellow;
         Console.WriteLine("------------测试相同订单------------");
         Console.ForegroundColor = ConsoleColor.White;
         OrderPay(firstOrderId, 1, lockType);
         OrderPay(firstOrderId, 2, lockType);
         OrderPay(firstOrderId, 3, lockType);
         Thread.Sleep(10000);

         Console.ForegroundColor = ConsoleColor.Yellow;
         Console.WriteLine("------------测试不同订单------------");
         Console.ForegroundColor = ConsoleColor.White;
         OrderPay(firstOrderId, 1, lockType);
         OrderPay(secondOrderId, 1, lockType);
         OrderPay(thirdOrderId, 1, lockType);
     }

     static void OrderPay(string orderId, int threadNo, LockType lockType)
     {
         new Thread(() => new Payment(orderId, threadNo).Pay(lockType)).Start();
         Thread.Sleep(10);
     }
 }
  public class Payment
  {
      private readonly string LockString;
      public readonly int ThreadNo;
      private readonly Object LockObj = new object();
      private static readonly Object StaticLockObj = new object();

      public Payment(string orderID, int threadNo)
      {
          LockString = orderID;
          ThreadNo = threadNo;
      }

      public void Pay(LockType lockType)
      {
          ShowMessage("等待锁资源");
          switch (lockType)
          {
              case LockType.LockThis:
                  lock (this)
                  {
                      showAction();
                  }
                  break;
              case LockType.LockString:
                  lock (LockString)
                  {
                      showAction();
                  }
                  break;
              case LockType.LockObject:
                  lock (LockObj)
                  {
                      showAction();
                  }
                  break;
              case LockType.LockStaticObject:
                  lock (StaticLockObj)
                  {
                      showAction();
                  }
                  break;
          }
          ShowMessage("释放锁");
      }

      private void showAction()
      {
          ShowMessage("进入锁并开始操作");
          Thread.Sleep(2000);
          ShowMessage("操作完成,完成时间为" + DateTime.Now);
      }

      private void ShowMessage(string message)
      {
          Console.WriteLine(String.Format("订单{0}的第{1}个线程 {2}", LockString, ThreadNo, message));
      }

  }

  public enum LockType
  {
      LockThis = 0,
      LockString = 1,
      LockObject = 2,
      LockStaticObject = 3
  }

lock (this) result:
Here Insert Picture Description

It can be seen lock (this), if this is a normal class non-static non-singleton, then the lock (this) does not meet our needs, even in addition to the current thread and do not see any effect.

lock (string) Result:

Here Insert Picture Description
Lock (LockString) from the comparison results, fit the requirements, but due to the special string for string reside CRL mechanism, different variables for the same string with a string value managed heap memory block to point to. May result in similar post-conflict order to pay the same business development brought about by the same identification ID ID string value of orders placed with other services, this will cause the thread mutual exclusion between different services

lock (object) results:

Here Insert Picture Description
Can thereby change the object typeof operator or obtained by reflection, nature, and lock (this) as

lock (staticObject) Results:

Here Insert Picture Description
Lock (StaticObject) to achieve the same sum for orders thread mutually exclusive, but can not meet the orders for different pen the same way mutually exclusive.

Summarize : When a thread to synchronize access to the shared resources, the locking specific object instance (e.g., private readonly object balanceLock = new object ();) or the other is unlikely to be as independent code lock object part instance. Avoid using the same lock object instance to different shared resources, as this may lead to a deadlock or lock contention. In particular, avoid the following objects are used as lock objects :

  • this (the caller can use as a lock).
  • Examples of Type (typeof operator can get through or reflected).
  • Examples of the string, the string comprising text, (which may be temporarily stored).
Published 37 original articles · won praise 3 · Views 6335

Guess you like

Origin blog.csdn.net/huan13479195089/article/details/88806010