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
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);
}
}
}
}