lock(this) is actually a pit

In this case, only one machine is considered, and multiple servers can use distributed locks. For thread safety reasons, you may see the emergence of lock in many scenarios, especially in the processing of fund class. But does lock(this) really meet your needs? Here is an example

We don't have much theoretical knowledge. Back to the business scenario, for example, our requirement is that when an order enters a process with a higher security priority, threads should be mutually exclusive. As for the reason, here's another concept. When most orm do update operations, they actually do all parameter update. The so-called all parameter update. If there are 10 fields in an order table, we only need to update one of the amount fields, but in the traditional orm framework, all fields are actually assigned in the entity class of the order, while in the update operation, these fields are all In the high concurrency scenario, if there are two threads operating on the same order, and there is no additional protection program (such as database lock, version number, etc.), the latter thread update may cover the previous thread operation in this traditional framework. So the way of lock can be regarded as a protective wall. So let's take a look at the differences between the four different ways of lock (not the four categories) through examples

The code is very simple. It's attached directly after the screenshot of the result

   1. Lock(this)

It can be seen that lock(this). If this is a normal class, non static and non singleton, then lock(this) does not meet our needs, or even has no effect except for the current thread.

  2. Lock(LockString)

Lock(LockString) meets the requirements from the result. For the same order, the threads are mutually exclusive. For different orders, the same class is used without interference. But according to your reply, LockString is not suitable for locks.

  3. Lock(Object)

Lock(Object) is the same as Lock(this), because root cause 2 is the same. Recommend!

  4. Lock(StaticObject)

Lock(StaticObject) implements the mutual exclusion for the same order thread, but it does not conform to the mutual exclusion for different orders.

The conclusion is clear at a glance, and the content of the theory is not repeated. Code below
`
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("------------Test the same order------------");
        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("------------Test different orders------------");
        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("Wait for lock resource");
        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("Release lock");
    }

    private void showAction()
    {
        ShowMessage("Enter lock and start operation");
        Thread.Sleep(2000);
        ShowMessage("Operation completed,Completed on" + DateTime.Now);
    }

    private void ShowMessage(string message)
    {
        Console.WriteLine(String.Format("Order{0}The first{1}Thread {2}", LockString, ThreadNo, message));
    }

}

public enum LockType
{
    LockThis = 0,
    LockString = 1,
    LockObject = 2,
    LockStaticObject = 3
}
`
//I hope it will help you.

Tags: ASP.NET Database

Posted on Fri, 07 Feb 2020 07:59:30 -0800 by jchemie