C # multithreaded Learning (v) thread synchronization and conflict resolution

Source: Internet
Author: User
Tags ticket

from:74358257

First of all, the example of a thread is not synchronized, the following is a ticket to the ticket sales, a number of conductors to sell 100 tickets, the code is as follows:

Using System;Using System.Text;Using System.Collections.Generic;Using System.threading;namespace threadtest{class Program {class Threadlock {Private Thread thread_1;Private Thread thread_2;Private list<Int> tickets;PrivateObject Objlock =NewObject ();Object Lock ObjectPublicThreadlock () {thread_1 =New Thread (Run); Thread_1.name ="Sailer_1"; Thread_2 =New Thread (Run); Thread_2.name ="Sailer_2"; }PublicvoidStart () {tickets =New list<Int> (100);Forint i =1; I <= 100; i++) {tickets. ADD (i); } thread_1.start (); Thread_2.start (); } public void Run () {while (tickets. Count > 0) {int get = tickets[< Span class= "Hljs-number" >0]; Console.WriteLine ( "{0} Sail a ticket, ticket number: {1}", Thread.CurrentThread.Name, get. ToString ()); Tickets. RemoveAt (0); Thread.Sleep (1);}} } static void Main () {Threadlock TK = new threadlock (); TK. Start (); Console.readkey (); } }} 
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21st
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

The above is a mock ticketing system, two threads to a ballot boxes to operate, each time to take out the top of the ticket, and then output, run after the view results will be found on the same ticket, two threads are likely to sell at the same time, as follows:

The reason for the above situation is that in the case of multi-threaded, the execution order of the thread is not controllable, the above situation may occur, the specific reason may be as follows:

Please look at the code:

                        int get = tickets[0];                        Console.WriteLine("{0} sail a ticket ,ticket number :{1} ",                        Thread.CurrentThread.Name, get.ToString()); tickets.RemoveAt(0);
    • 1
    • 2
    • 3
    • 4

For example, thread A has not exported and deleted this ticket since it was determined to take the bottom ticket from tickets, and the CPU time allocated by thread A is exhausted.

Then another thread B executes, thread B has enough time to confirm the ticket that thread a just confirmed, and then takes out that ticket, pulls out the ticket, and then outputs and deletes the vote, and then passes the CPU control to thread A.

It is also a thread a execution, thread A because just already determined the selected ticket, so the direct output of the ticket, and then the bottom of the ticket deleted. So you can see that there is a jump to get tickets, such as: 1,3,5,7, ...

Thread synchronization

The reason for this is that multiple threads are working on the same resource, so it should be avoided as much as possible in multithreaded programming, although in some cases it does not, which requires some means to ensure that this is not the case, which is called thread synchronization.
There are several ways to implement thread synchronization in C #: Lock, Mutex, Monitor, Semaphore, interlocked, and ReaderWriterLock. Synchronization policies can also be divided into synchronization contexts, synchronizing code areas, and manually synchronizing several ways.

Lock Sync

For the above code, to ensure that there is no confusion, you can use the Lock keyword to achieve, the problem is to determine whether the remaining votes is greater than 0, if more than 0 from the current total number of votes subtracted from the largest ticket, so you can lock processing this part, the code is as follows:

 public 
     
      void 
      run () {while ( Tickets. Count > 0) {lock (objlock) {if ( Tickets. Count > 0) {int get = tickets[< Span class= "Hljs-number" >0]; Console.WriteLine ( "{0} Sail a ticket, ticket number: {1}", Thread.CurrentThread.Name, get. ToString ()); Tickets. RemoveAt (0); Thread.Sleep (1);}} } }
      
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

After this process, the ticketing system becomes normal and the effect is as follows:

In general, the lock statement is an efficient way to synchronize small blocks of code that do not span multiple methods, that is, the lock statement can only be used between parts of a method and not across a method.

Monitor class

For the above processing methods, we use the Monitor class to deal with the following code:

public void Run () {while (tickets. Count >0) {Monitor; if (Tickets0) {int get = Tickets[0] "{0} Sail a ticket, ticket number: {1}", Thread0) 1) ;} Monitor           
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

Run can know that this code and the lock method result is the same, of course, lock is implemented with the Monitor class, in addition to locking the code area, we can also use the Monitor class of the wait () and pulse () method.

The Wait () method temporarily frees the currently alive lock and keeps the current object in a blocked state
The Pulse () method is to notify the waiting state that an object is ready, and it will release the lock in a minute.

Let's implement a producer and consumer model where the producer thread is responsible for producing the data, and the consumer thread will produce the output from the producer, the code is as follows:

Using System;Using System.Text;Using System.Collections.Generic;Using System.threading;namespace threadtest{class Program {PublicClass Cell {int cellcontents;Content inside the Cell objectBOOL Readerflag =FalseStatus flag, True when it can be read, False is being writtenPublicIntReadfromcell () {Lock (ThisThe lock keyword guarantees that the current block of code allows only one thread to enter execution at the same time {if (!readerflag)If it is not read now {try {Wait for the Writetocell method to call the Monitor.pulse () method to wake the thread monitor.wait (this); }catch (SynchronizationLockException e) {Console.WriteLine (e);}} Console.WriteLine ("Use: {0}", cellcontents); Readerflag =FalseResets the READERFLAG flag to indicate that the consumption behavior has been completed Monitor.pulse (this);Notifies the Writetocell () method (the method executes in another thread, waits)}return cellcontents; }PublicvoidWritetocell (int n) {Lock (This) {if (Readerflag) {try {monitor.wait (this); }catch (SynchronizationLockException e) {Console.WriteLine (e) is called in the non-synchronized code area when the synchronization method (that is, the monitor class is not a method other than enter); }} cellcontents = n; Console.WriteLine ("Produce: {0}", cellcontents); Readerflag =True Monitor.pulse (this);Notifies the other thread of the waiting Readfromcell () method}}}PublicClass Cellprod {cell cell;The Cell object being manipulatedint quantity =1;Producer production times, initialized to 1PublicCellprod (Cell box,int request) {cell = box; quantity = Request;}PublicvoidThreadRun () {for (int looper =1; Looper <= Quantity; looper++) cell. Writetocell (Looper);Producer writes information to the Action object}}PublicClass Cellcons {cell cell;int quantity =1;PublicCellcons (Cell box,int request) {constructor cell = box; Quantity = Request; }PublicvoidThreadRun () {int valreturned;for (int looper =1; Looper <= Quantity; looper++) valreturned = cell. Readfromcell ();The consumer reads information from the operand}}PublicStaticvoidMain (string[] args) {int result =0;A flag bit, if 0 indicates that the program is not faulted, if 1 indicates that there was an error in the cell cell =new Cell (); //below uses cell to initialize Cellprod and cellcons two classes, production and consumption times are 20 times cellprod prod = new cellprod (cell, 20); Cellcons cons = new cellcons (cell, 20); Thread producer = new Thread (new ThreadStart. ThreadRun)); Thread consumer = new Thread (new ThreadStart. ThreadRun)); //producer Threads and consumer threads have been created, but did not begin to execute try {producer. Start (); Consumer. Start (); Producer. Join (); Consumer. Join (); Console.ReadLine (); } catch (threadstateexception e) {//when a thread cannot perform the requested operation because of the state in which it is located Console.WriteLine (e); result = 1;}} }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21st
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127

In this routine, the producer thread and the consumer thread are alternately, and the producer writes a number that the consumer reads and outputs immediately.
Synchronization is done by waiting for Monitor.pulse ().
First the producer produces a data, and at the same time the consumer waits, until the producer's pulse (pulses) informs it that the production has been completed, and then the consumer enters the state of consumption. The results are as follows:

Almost so, the above approach has helped us to solve most of the problems that may arise in multi-threading, and the rest is no longer covered, and the processing of synchronization is over.

C # multithreaded Learning (v) thread synchronization and conflict resolution

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.