Multithreading programming learning notes-basics (3) and multithreading programming learning notes
Multi-thread programming learning notes-basics (1) Introduction to multi-thread programming learning notes-basics (2) Ix. Passing parameters to threads
1. The Code is as follows.
Using System; using System. collections. generic; using System. linq; using System. text; using System. threading; // introduce the thread using System. diagnostics; namespace ThreadConsoleApp {class Program {static void Main (string [] args) {Console. writeLine ("START, pass parameter to Thread"); var fore = new ThreadBackground (10); Thread t = new Thread (fore. countNumber); t. name = "thread 1"; // start thread t. start (); t. join (); Console. writeLine ("--------------------------"); var t2 = new Thread (Count); t2.Name = "Thread 2"; t2.Start (8); t2.Join (); Console. writeLine ("--------------------------"); var t3 = new Thread () => CountNumber (12); t3.Name = "Thread 3"; t3.Start (); t3.Join (); Console. writeLine ("--------------------------"); int I = 10; var t4 = new Thread () => PrintNumber (I); t4.Name = "Thread 4"; I = 20; var t5 = new Thread () => PrintNumber (I); t5.Name = "Thread 5"; t4.Start (); t5.Start (); Console. read ();} static void CountNumber (int cnt) {for (int I = 0; I <cnt; I ++) {Thread. sleep (1, 500); Console. writeLine (string. format ("{0} print the {} number", Thread. currentThread. name, I. toString ("N0");} static void Count (object cnt) {CountNumber (int) cnt);} static void PrintNumber (int num) {Console. writeLine (string. format ("{0} print the {} number", Thread. currentThread. name, num. toString ("N0 ")));}}}
2. The result is shown in.
Thread 1, we pass parameters by instantiating objects.
Thread 2, we use Thread. Start () to pass parameters, but this method only receives a single parameter and is of the object type.
Thread 3: We use lambda expressions to pass parameters. lambda expressions define a method that does not belong to any class and call the method we actually want to execute, parameters are also passed to the thread.
Thread 4 and thread 5 are a problem of passing Parameters Using lambda expressions. That is, when multiple lambda expressions share one variable, they share the value of this variable. As shown in thread 4 and thread 5, 10 is not printed, and only 20 is printed.
10. Use lock to lock
1. The Code is as follows:
Using System; using System. collections. generic; using System. linq; using System. text; using System. threading; // introduce the thread using System. diagnostics; namespace ThreadConsoleApp {class Program {static void Main (string [] args) {Console. writeLine ("START, lock the Thread"); var c = new Counter (); Thread t = new Thread () => Count (c )); var t3 = new Thread () => Count (c); var t2 = new Thread () => Count (c); t. name = "thread 1"; // start thread t. start (); t2.Name = "thread 2"; t2.Start (); t3.Name = "thread 3"; t3.Start (); t. join (); t2.Join (); t3.Join (); Console. writeLine (string. format ("Total threads without locks: {0}", c. count); Console. writeLine ("----------------------------"); var c1 = new CounterLock (); var t4 = new Thread () => Count (c1); t4.Name = "Thread 4 "; var t5 = new Thread () => Count (c1); t5.Name = "Thread 5"; var t6 = new Thread () => Count (c1 )); t6.Name = "thread 6"; t4.Start (); t5.Start (); t6.Start (); t4.Join (); t5.Join (); t6.Join (); Console. writeLine (string. format ("Total number of locked threads: {0}", c1.Count); Console. read ();} static void Count (CountBase cnt) {for (int I = 0; I <100000; I ++) {cnt. incerement (); cnt. dncerement () ;}} abstract class CountBase {public abstract void Incerement (); public abstract void Dncerement ();} class Counter: CountBase {public int Count {get; private set;} public override void Dncerement () {Count --;} public override void Incerement () {Count ++ ;}} class CounterLock: countBase {private readonly object objSync = new object (); public int Count {get; private set;} public override void Dncerement () {lock (objSync) {Count --;}} public override void Incerement () {lock (objSync) {Count ++ ;}}}}
2. The result is as follows:
The main thread first creates a Counter instance object, which defines a simple Counter that can be added or subtracted. Then we create three threads, which share a Counter object. Because shared variables are not locked, the current thread operates shared variables before the previous thread ends, we will get different counting values, as shown in. To prevent this situation, we need to lock the shared variables. Use the lock keyword to lock the object, so that no other thread can operate on shared variables before a thread operation is completed.
11. Resource locking by Moniter
1. The Code is as follows:
Using System; using System. collections. generic; using System. linq; using System. text; using System. threading; // introduce the thread using System. diagnostics; namespace ThreadConsoleApp {class Program {static void Main (string [] args) {Console. writeLine ("START, Thread DeadLock"); var lock1 = new object (); var lock2 = new object (); Thread t = new Thread () => DeadLock (lock1, lock2); t. name = "thread 1"; // start thread t. start (); lock (lock2) {Thread. sleep (2000); if (Monitor. tryEnter (lock1, TimeSpan. fromSeconds (5) {Console. writeLine ("requesting resources within the specified time");} else {Console. writeLine ("time-out, unable to get resources") ;}} new Thread () => DeadLock (lock1, lock2 )). start (); Console. writeLine ("-----------------------------"); lock (lock2) {Thread. sleep (1, 1000); Console. writeLine (string. format ("deadlock thread"); lock (lock1) {Console. writeLine ("successful resource request") ;}} Console. read ();} /// <summary> /// deadlock method /// </summary> /// <param name = "objLock1"> </param> /// <param name = "objLock2"> </param> static void DeadLock (object objLock1, object objLock2) {lock (objLock1) {Thread. sleep (2000); lock (objLock2) {Console. writeLine ("deadlock ");}}}}}
2. The result is as follows:
First, let's look at the deadlock method. This method first locks the lock1 object, and then waits for 2 seconds to lock the lock2 object. Then, this method is started in the Child thread.
The master thread first locks the lock2 object, and then waits to obtain the lock1 object. Because the sub-thread locks the lock1 object, wait for the lock2 object. This causes a deadlock.
12. multi-thread Exception Handling
1. The Code is as follows:
Using System; using System. collections. generic; using System. linq; using System. text; using System. threading; // introduce the thread using System. diagnostics; namespace ThreadConsoleApp {class Program {static void Main (string [] args) {Console. writeLine ("START, exception handling"); Thread t = new Thread (FaultyThread); t. name = "thread 1"; // start thread t. start (); t. join (); try {t = new Thread (ExpectThread); t. start ();} catch (Exception ex) {Console. writeLine ("exception information:" + ex. message);} Console. read ();} static void ExpectThread () {Console. writeLine (string. format ("Exception Handling"); Thread. sleep (2000); throw new Exception ("throw Exception");} static void FaultyThread () {try {Console. writeLine (string. format ("Exception Handling 2"); Thread. sleep (1000); throw new Exception ("throw Exception 2");} catch (Exception ex) {Console. writeLine (string. format ("Exception Handling 2: {0}", ex. message ));}}}}
2. The result is shown in.
Two Methods for exception handling are defined in the program. One is used to handle the exception, and the other is not used to handle the exception. Last. The program crashed.