1. How to sell tickets
classTicketrest {intTicket =1; intMax =0; PublicTicketrest (intmax) {Max=Max; } /// <summary> ///not locked/// </summary> /// <param name= "num" ></param> Public voidSellticketnolock (intnum) { while(Ticket <=Max) { if(Ticket >Max) Break;//it must be judged here. Console.WriteLine ($"Window {num}| conductor {Thread.CurrentThread.ManagedThreadId}: Ticket sold [{ticket}], remaining {max-ticket}"); Ticket++; Task.delay ( $); } } /// <summary> ///Locking/// </summary> /// <param name= "num" ></param> Public voidSellticketaddlock (intnum) { while(Ticket <=Max) { Lock( This) { if(Ticket >Max) Break;//it must be judged here. Console.WriteLine ($"Window {num}| conductor {Thread.CurrentThread.ManagedThreadId}: Ticket sold [{ticket}], remaining {max-ticket}"); Ticket++; Task.delay ( $); } } }
View Code
2. Use thred to invoke the method of selling tickets
An unlocked condition (calling method Sellticketnolock) will cause a ticket to be sold multiple times and the remainder of the ticket does not meet the situation.
3. Call the Ticket method using task
Traps for closures:
for (int i = 0; i < Windowcount; i++)
{
Tasklst. Add (Task.run (() = {Ticketrest2.sellticketaddlock (i);}));
}
The last I value is 5 instead of the original I value.
Workaround use temporary variable, instead:
for (int i = 0; i < Windowcount; i++)
{
int temp = i;
Tasklst. ADD (Task.run () = {Ticketrest2.sellticketaddlock (temp);});
}
The locking (Sellticketaddlock) ticket did not duplicate the remaining ticket and there was no error.
The complete code:
classProgram {Static voidMain (string[] args) { //Sellthread ();Selltaskdemo (); Console.ReadLine (); } Private Static intTicketcount = -;//Total 20 Tickets Private Static intWindowcount =5;//A total of 5 windows simultaneous ticketing /// <summary> /////Demo multi-threaded sell ticket case-thread Way/// </summary> Static voidSellthread () {Try{ticketrest ticketrest=Newticketrest (Ticketcount); for(inti =0; i < Windowcount; i++) {thread thread=NewThread (() ={ticketrest.sellticketnolock (i);}); Thread. Start (); } } Catch(Exception ex) {LoggerFactory.Instance.Logger_Error (ex); Console.WriteLine ($"{ex. message}| {Ex. GetType (). fullname}| {Ex. targetsite}| {Ex. StackTrace}"); } } /// <summary> ///Demo multi-threaded sell ticket case-task Way/// </summary> Static voidSelltaskdemo () {Try{Stopwatch Stopwatch1=NewStopwatch (); Stopwatch1. Start (); Ticketrest TicketRest1=Newticketrest (Ticketcount); Ticketrest1.sellticketaddlock (0); Stopwatch1. Stop (); Console.WriteLine ($"use a single-threaded way to consume time: {stopwatch1. Elapsedmilliseconds} milliseconds"); Stopwatch STOPWATCH2=NewStopwatch (); Stopwatch2. Start (); Ticketrest TicketRest2=Newticketrest (Ticketcount); varTasklst =NewList<task>(); for(inti =0; i < Windowcount; i++) { inttemp =i; Tasklst. ADD (Task.run ()={ticketrest2.sellticketaddlock (temp);})); } task.waitall (Tasklst. ToArray ()); Stopwatch2. Stop (); Console.WriteLine ($"Use Multithreading: Code snippet Run time ({stopwatch2. Elapsedmilliseconds} milliseconds)"); } Catch(Exception ex) {LoggerFactory.Instance.Logger_Error (ex); Console.WriteLine ($"{ex. message}| {Ex. GetType (). fullname}| {Ex. targetsite}| {Ex. StackTrace}"); } } } classTicketrest {intTicket =1; intMax =0; PublicTicketrest (intmax) {Max=Max; } /// <summary> ///not locked/// </summary> /// <param name= "num" ></param> Public voidSellticketnolock (intnum) { while(Ticket <=Max) { if(Ticket >Max) Break;//it must be judged here. Console.WriteLine ($"Window {num}| conductor {Thread.CurrentThread.ManagedThreadId}: Ticket sold [{ticket}], remaining {max-ticket}"); Ticket++; Task.delay ( $); } } /// <summary> ///Locking/// </summary> /// <param name= "num" ></param> Public voidSellticketaddlock (intnum) { while(Ticket <=Max) { Lock( This) { if(Ticket >Max) Break;//it must be judged here. Console.WriteLine ($"Window {num}| conductor {Thread.CurrentThread.ManagedThreadId}: Ticket sold [{ticket}], remaining {max-ticket}"); Ticket++; //Task.delay ($);Thread.Sleep ( -);//simulate time-consuming operations } } } }
View Code
LoggerFactory.Instance.Logger_Error (ex); This is an output exception and can be replaced with Console.WriteLine.
References:
Understanding closures in C #: https://www.cnblogs.com/jiejie_peng/p/3701070.html
Talking about concurrency and parallelism (i): http://www.cnblogs.com/yangecnu/p/Something-about-Concurrent-and-Parallel-Programming.html
Multithreading Series 1: Classic Selling tickets