C# Lock 实例锁和静态锁区别

发布时间 2023-10-30 12:03:01作者: 蛋蛋十二月

Lock 实例锁和静态锁区别

public class SharedResource
    {
        private readonly object lockObject = new object();

        private readonly static object lockstaticObject = new object();
        static int counter = 0;

        public int IncrementCounter()
        {
            lock (lockObject)
            {
                Console.WriteLine(counter.ToString());
                counter++;
                return counter;
            }
        }
        public int IncrementCounter2()
        {
            lock (lockstaticObject)
            {
                Console.WriteLine(counter.ToString());
                counter++;
                return counter;
            }
        }
    }
    internal class Program
    {

        static void Main(string[] args)
        {
            List<Task> tasks = new List<Task>();
            for (int i = 0; i < 20; i++)
            {
                tasks.Add(
                        Task.Run(() =>
                        {
                            new SharedResource().IncrementCounter2();
                        })
                );
            }

            Task.WhenAll(tasks).Wait();

        }

这段代码中的 IncrementCounterIncrementCounter2 两个方法都用于增加 counter 变量的值,并在每次增加后返回新的值。它们的主要区别在于用于同步的锁对象:

  1. IncrementCounter 方法使用一个实例锁对象 lockObject。这意味着每次只有一个线程可以访问此方法。如果有其他线程试图同时访问此方法,它们将会被阻塞,直到当前线程完成此方法的执行。
  2. IncrementCounter2 方法使用一个静态锁对象 lockstaticObject。这意味着每次只有一个线程可以访问此静态方法,无论有多少实例。如果有其他线程试图同时访问此方法,它们将会被阻塞,直到当前线程完成此方法的执行。

使用实例锁和静态锁的区别在于,实例锁只锁当前实例,而静态锁会锁整个类型。因此,如果你创建了多个 SharedResource 实例,每个实例都有自己的 lockObject,所以它们不会相互阻塞。然而,对于 IncrementCounter2,由于它使用的是静态锁,所以即使你创建了多个 SharedResource 实例,其他线程试图访问任何实例的 IncrementCounter2 方法时都会被阻塞,直到第一个线程完成执行。

总结:静态锁的所范围很大。再合适的场景要使用不同的锁