Let's take a look at the simple multi-threaded console.Program:
Using System;
Using System. Threading;
NamespaceManualreseteventstudy
{
Class Threadclass
{
Static Void T1 ()
{
For ( Int X = 1 ; X <= 5 ; X ++ )
{
Thread. Sleep ( 500 );
Console. writeline ( " X of T1: " + X );
}
}
Static Void T2 ()
{
For ( Int X = 1 ; X <= 5 ; X ++ )
{
Thread. Sleep ( 500 );
Console. writeline ( " X of T2: " + X );
}
}
Static VoidMain (String[] ARGs)
{
Thread thrd1= NewThread (T1 );
Thrd1.start ();
Thread thrd2= NewThread (T2 );
Thrd2.start ();
For ( Int X = 1 ; X <= 5 ; X ++ )
{
Thread. Sleep ( 500 );
Console. writeline ( " X in the main thread: " + X );
}
Console. Read ();
}
}
}
In the main method of the entry, two threads are created to call Methods t1 and t2 respectively, plus the main thread itself, with three threads. After running, all three threads are counting output, and the results are similar to the following:
X: 1 of T2
X: 1 of T1
X: 1 in the main thread
X: 2 of T2
X: 2 of T1
X: 2 in the main thread
X: 3 of T2
X: 3 of T1
X: 3 in the main thread
X: 4 of T2
X: 4 of T1
X: 4 in the main thread
X: 5 of T2
X: 5 of T1
X: 5 in the main thread
The order of the three threads.CodeWe cannot control the CPU. The Sky knows who starts first/WHO ends first, and it is "Parallel" processing. It depends entirely on the mood of the CPU at the time.
Q: If the requirement changes, for example, when the main thread is executed at a specific position (or time point), other threads can get involved. How can this problem be solved? (This is very common in practice. For example, the entry parameter of a calculation depends on the result of another calculation. For example, before calculating the monthly salary, we must first calculate the employee's attendance for the current month)
The system. Threading namespace has a manualresetevent class. You can do this:
Using System;
Using System. Threading;
NamespaceManualreseteventstudy
{
ClassThreadclass
{
StaticManualresetevent MRE= NewManualresetevent (False);
Static Void T1 ()
{
Mre. waitone ( 1000 ); // Wait 1 second and start it on your own
For ( Int X = 1 ; X <= 5 ; X ++ )
{
Thread. Sleep ( 500 );
Console. writeline ( " X of T1: " + X );
}
}
Static Void T2 ()
{
Mre. waitone (); // Wait until someone calls MRE. Set () to send a signal.
For ( Int X = 1 ; X <= 5 ; X ++ )
{
Thread. Sleep ( 500 );
Console. writeline ( " X of T2: " + X );
}
}
Static VoidMain (String[] ARGs)
{
Thread thrd1= NewThread (T1 );
Thrd1.start ();
Thread thrd2= NewThread (T2 );
Thrd2.start ();
For ( Int X = 1 ; X <= 5 ; X ++ )
{
Thread. Sleep ( 500 );
Console. writeline ( " X in the main thread: " + X );
If (X = 3 )
{
Mre. Set (); // Notify all the waiting threads: "Comrades, please move ":)
}
}
Console. Read ();
}
}
}
In the T1 method, we use MRE. waitone (1000); let the thread that calls this method wait for 1 second first. In the T2 method, we use MRE. waitone () waits infinitely, and then manually calls MRE when the count in the main thread reaches 3. the Set () method wakes up all waiting threads. The running result is similar to the following:
X: 1 in the main thread
X: 2 in the main thread
X: 1 of T1
X: 3 in the main thread
X: 2 of T1
X: 1 of T2
X: 4 in the main thread
X: 3 of T1
X: 5 in the main thread
X: 2 of T2
X: 4 of T1
X: 3 of T2
X: 5 of T1
X: 4 of T2
X: 5 of T2