I have this code which creates a deadlock :
void Main()
{
ClassTest test = new ClassTest();
lock(test)
{
Task t1 = new Task(() => test.DoWorkUsingThisLock(1));
t1.Start();
t1.Wait();
}
}
public class ClassTest
{
public void DoWorkUsingThisLock(int i)
{
Console.WriteLine("Before " + i);
Console.WriteLine ("Current Thread ID is = "+Thread.CurrentThread.ManagedThreadId);
lock(this)
{
Console.WriteLine("Work " + i);
Thread.Sleep(1000);
}
Console.WriteLine("Done " + i);
}
}
Result :
Before 1
(and deadlock....)
I know that this is a bad practice to lock over instances beyond code's control or , this
. But it's just for this question.
I can understand why a deadlock is created here.
The main thread acquires the lock(test)
in main
and then a new thread starts to invoke DoWorkUsingThisLock
- there it tries to acquire a lock over the same instance variable and it's stuck ( because of t1.Wait()
at main
)
OK
But I've seen this answer here which also creates deadlock.
void Main()
{
ClassTest test = new ClassTest();
lock(test)
{
Parallel.Invoke (
() => test.DoWorkUsingThisLock(1),
() => test.DoWorkUsingThisLock(2)
);
}
}
public class ClassTest
{
public void DoWorkUsingThisLock(int i)
{
Console.WriteLine("Before ClassTest.DoWorkUsingThisLock " + i);
lock(this)
{
Console.WriteLine("ClassTest.DoWorkUsingThisLock " + i);
Thread.Sleep(1000);
}
Console.WriteLine("ClassTest.DoWorkUsingThisLock Done " + i);
}
}
The result is :
Before ClassTest.DoWorkUsingThisLock 1
Before ClassTest.DoWorkUsingThisLock 2
ClassTest.DoWorkUsingThisLock 1 // <---- how ?
ClassTest.DoWorkUsingThisLock Done 1
Question:
How come it DID acquire the lock for the first invocation (DoWorkUsingThisLock(1)
)? The lock
at main
is still blocked due to Parallel.Invoke
which DOES block !
I don't understand how the thread has succeeded to enter the lock(this)
section.