多线程线性 lock

Posted 空明流光

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程线性 lock相关的知识,希望对你有一定的参考价值。

有时我们lock一段代码或许要根据某个变量的值,值相同则不允许有两个或以上的方法并行运行,我在工作中就遇到了,有100个值,相同的参数值不能并行运行。

还有就是一个被lock的方法递归调用会不会死锁,因为需要lock同一个变量。答案当然是不会死锁。

下面是一个测试demo

class Program
    {
        private static object a = new object();
        private static object b = new object();
        private static object c = new object();
        private static Hashtable list = Hashtable.Synchronized(new Hashtable());

        static void Main(string[] args)
        {
            //所有i不相等的线程将同步执行并返回结果
            new Thread(new ParameterizedThreadStart(delegate(object obj) {
                Test(0, 2000);
                Console.WriteLine("1");
            })).Start();

            new Thread(new ParameterizedThreadStart(delegate(object obj)
            {
                Test(1, 2000);
                Console.WriteLine("1+");
            })).Start();

            //所有i==2的线程将顺序执行
            new Thread(new ParameterizedThreadStart(delegate(object obj)
            {
                Test(2, 2000);
                Console.WriteLine("2");
            })).Start();

            new Thread(new ParameterizedThreadStart(delegate(object obj)
            {
                Test(2, 2000);
                Console.WriteLine("3");
            })).Start();

            new Thread(new ParameterizedThreadStart(delegate(object obj)
            {
                Test(2, 2000);
                Console.WriteLine("4");
            })).Start();

            new Thread(new ParameterizedThreadStart(delegate(object obj)
            {
                Test(2, 2000);
                Console.WriteLine("5");
            })).Start();

            new Thread(new ParameterizedThreadStart(delegate(object obj)
            {
                Test(2, 2000);
                Console.WriteLine("6");
            })).Start();

            //两次lock同一变量不会死锁
            new Thread(new ParameterizedThreadStart(delegate(object obj)
            {
                Test2(3, 2000);
                Console.WriteLine("7");
            })).Start();

            Console.ReadKey();
        }

        /// <summary>
        /// 对于i相同的线程进行阻塞保证不会并行多个
        /// </summary>
        /// <param name="i"></param>
        /// <param name="j"></param>
        public static void Test(int i,int j)
        {
            if (!list.ContainsKey(i))
                list.Add(i, DateTime.Now);

            lock (list[i])
            {
                Thread.Sleep(j);
            }
        }
        
        //多次lock同一变量测试是否会死锁
        public static void Test2(int i, int j, bool isFirstRun = true)
        {
            if (!list.ContainsKey(i))
                list.Add(i, DateTime.Now);

            lock (list[i])
            {
                Thread.Sleep(j);
                if (isFirstRun)
                    Test2(i, j, false);
            }
        }
    }

程序输出如下:

1+
2
1
3
7
4
5
6

 

以上是关于多线程线性 lock的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程与并发库高级应用-工具类介绍

Java多线程与并发库高级应用-工具类介绍

多线程安全问题之Lock显示锁

Java多线程Lock

Java多线程学习篇Lock

c#初学-多线程中lock用法的经典实例