Hanging out on the Internet a few days ago, I accidentally saw such a question and its answer, as shown below:
Based on the knowledge of thread security, analyze the followingCodeDoes a deadlock occur when I> 10 of the test method is called? And briefly explain the reasons.
code highlighting produced by actipro codehighlighter (freeware)
http://www.CodeHighlighter.com/
--> Public void test ( int I)
{< br> lock ( This )
{< br> If (I > 10 )
{< br> I -- ;< br> test (I );
}< BR >}
A: No deadlock will occur (but one int is passed by value, so each change is only a copy, so no deadlock will occur. But if you replace int with an object, the deadlock will occur)
When I see this question, I have only two answers in my mind. 1. deadlock occurs. 2. No. ^_^ Said when not speaking. I think the reason for the deadlock is that the same thread can only enter the lock statement once. If the thread does not exit the lock statement, it cannot enter the lock statement again. The reason for no deadlock is that the same thread can enter the lock statement multiple times.
I ran this code into Vs and found that it was not in a deadlock. So I wanted to find an authoritative reason to explain it. Finally, in the second edition of CLR via C # (Chinese version, the 530th row on the 7th page of the Tsinghua University Press found the following description: "The same thing to note is that threads can recursively own synchronization blocks ". That is, the lock statement can be recursively called by the same thread.
The preceding section only discusses the single thread. The following code shows the two threads:
Code
Using System;
Using System. Threading;
Namespace Lockdemo
{
Class Program
{
Static Void Main ( String [] ARGs)
{
Program P = New Program ();
Myobj = New Myobj ();
// First thread
Thread thread1 = New Thread (P. test );
Thread1.name = " Thread1 " ;
// First thread
Thread thread2 = New Thread (P. test );
Thread2.name = " Thread2 " ;
// Start thread
Thread1.start (OBJ );
Thread2.start (OBJ );
Console. Read ();
}
Public Void Test ( Object OBJ)
{
Lock ( This )
{
If (Myobj) OBJ). Value > 10 )
{
(Myobj) OBJ). Value -- ;
Console. Write (thread. currentthread. Name + " : " );
Console. writeline (myobj) OBJ). value );
Thread. Sleep ( 10 );
Test (OBJ );
}
Else
{
Console. writeline (thread. currentthread. Name );
}
}
}
}
/// <Summary>
/// Encapsulate a value type in a class for convenient calling by multiple threads
/// </Summary>
Public Class Myobj
{
Public Int Value;
Public Myobj ()
{
// Assign the initial value to 20
Value = 20 ;
}
}
}
The running result is as follows:
Since thread1 first enters the lock statement, the lock remains occupied by thread1 and is called recursively until the conditions are not met. After thread1 releases the lock, when thread2 enters the lock statement, it is found that the current recursion condition is no longer met, that is, I <10, so exit directly.
What makes me feel strange is the answer provided on the Internet, that is, the text description in brackets. What is the lock applied to this object in the Code and what is the link with the passed parameter? The reason for finding an int is passed by value. It is strange to explain that no deadlock will occur.
Note: If you do not understand the technical principles behind lock, please refer to CLR via C.
References: CLR via C #, 2 pp., Tsinghua University Press