lock in C#

来源:互联网 发布:淘宝全网数据分析工具 编辑:程序博客网 时间:2024/04/28 22:17

http://msdn.microsoft.com/en-us/library/c5kehkcz(v=vs.110).aspx

lock ensures that one thread does not enter a critical section while another thread is in the critical section of code. If another thread attempts to enter a locked code, it will wait (block) until the object is released.

In general, avoid locking on a public type, orinstances beyond your code's control. The common constructs lock (this)lock (typeof (MyType)), and lock ("myLock") violate this guideline:

  • lock (this) is a problem if the instance can be accessed publicly.

  • lock (typeof (MyType)) is a problem if MyType is publicly accessible.

  • lock("myLock") is a problem because any other code in the process using the same string, will share the same lock.

    Best practice is to define a private object to lock on, or a private static object variable to protect data common to all instances.

If youlock(object) then at the same time, you are able to read/write object but you cannot use lock(object) again


Q & A:

1.Why nested lock not causing deadlock?

lock(a)   {      lock(a)      {         ....      }   }

Answer: If a thread already holds a lock, then it can "take that lock" again without issue.

2. example of "lock(this)" causing deadlock. 

Description: Class LockTest method TestLock() causing deadlock

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data;using System.Threading;namespace ConsoleApplication1{    class Program    {        static void Main(string[] args)        {            LockTest t=new LockTest();            MyThread thread = new MyThread();            Console.WriteLine("Before start thread");            Thread tid1 = new Thread(new ParameterizedThreadStart(thread.Thread1));            Thread tid2 = new Thread(new ParameterizedThreadStart(thread.Thread2));            tid1.Start(t);            tid2.Start(t);        }    }    public class MyThread    {        public  void Thread1(object t)        {            lock (t)            {               Thread.Sleep(1000);               lock (this)               {                   var tt = ((LockTest)t);                   tt.TestLock();               }            }        }        public  void Thread2(object t)        {            lock (this)            {                var tt = ((LockTest)t);                tt.TestLock();            }        }    }    class LockTest    {        public string _status = "";        public void TestLock()        {            lock (this)            {                Console.WriteLine("Lock Process Done");            }        }    }    }

3. lock on static variable will lock all instances

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data;using System.Threading;namespace ConsoleApplication1{    class Program    {        static void Main(string[] args)        {            LockTest t1 = new LockTest();            LockTest t2 = new LockTest();            MyThread thread = new MyThread();            Console.WriteLine("Before start thread");            Thread tid1 = new Thread(new ParameterizedThreadStart(thread.Thread1));            Thread tid2 = new Thread(new ParameterizedThreadStart(thread.Thread2));            tid1.Start(t1);            tid2.Start(t2);            Console.Read();        }    }    public class MyThread    {        public  void Thread1(object t)        {            var tt = ((LockTest)t);            tt.TestLock();        }        public  void Thread2(object t)        {            Thread.Sleep(1000);            var tt = ((LockTest)t);            tt.TestLock();        }    }    class LockTest    {        private static object _obj = new object();        public string _status = "";        public void TestLock()        {            lock (_obj)            {                Thread.Sleep(10000);                Console.WriteLine("Lock Process Done");                Console.WriteLine(_status);            }        }    }    }

4. lock on normal object only limit to current instance

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data;using System.Threading;namespace ConsoleApplication1{    class Program    {        static void Main(string[] args)        {            LockTest t1 = new LockTest();            LockTest t2 = new LockTest();            MyThread thread = new MyThread();            Console.WriteLine("Before start thread");            Thread tid1 = new Thread(new ParameterizedThreadStart(thread.Thread1));            Thread tid2 = new Thread(new ParameterizedThreadStart(thread.Thread2));            tid1.Start(t1);            tid2.Start(t2);            Console.Read();        }    }    public class MyThread    {        public  void Thread1(object t)        {            var tt = ((LockTest)t);            tt.TestLock();        }        public  void Thread2(object t)        {            Thread.Sleep(1000);            var tt = ((LockTest)t);            tt.TestLock();        }    }    class LockTest    {        private object _obj = new object();        public string _status = "";        public void TestLock()        {            lock (_obj)            {                Thread.Sleep(10000);                Console.WriteLine("Lock Process Done");                Console.WriteLine(_status);            }        }    }    }



原创粉丝点击