C # Multithreading series (vi)

Source: Internet
Author: User

Sync

When multiple threads share some data, we need to use synchronous technology to ensure that only one thread accesses the shared state at a time. Note that synchronization issues are related to contention and deadlock.

Cases:

Static intIDX =0;Static voidAdd () { for(inti =0; I <50000; i++) {idx++; }}Static voidMain () {Const intSIZE = +; Task[] Arr=NewTask[size];  while(true)    {         for(inti =0; i < SIZE; i++) {Arr[i]=NewTask (ADD); Arr[i].         Start (); //Start Multiple threads        }         for(inti =0; i < SIZE; i++) {Arr[i].          Wait (); //wait for thread to finish} Console.WriteLine (IDX); Thread.Sleep ( -); IDX=0;//Reset data, run again    }}

Results:

1717634
1652989
1444839
1272385
1558097
1297459
1968232
2000000

Obviously, not what we want, we expect the result to be 2000000 per run. This is because idx++ is not thread-safe, and its operations include getting a value from memory, incrementing the value by 1, and then saving it back into memory. These operations can be interrupted by the thread scheduler.

In this case, we need some synchronous methods to solve the problem.

    • lock The keyword marks a statement block as a critical section by obtaining a mutex for a given object, executing the statement, and then releasing the lock. Call  enter at the beginning of the block, and call  exit at the end of the block. This If another thread tries to enter the locked code, it waits (that is, is blocked) until the object is freed. A thread that, when blocked, does not occupy cpu resources.
Static Object New Object (); Static void Add () {    for (int050000; i++)    {           Lock  (locker)            idx+ +;    }}

    • The interlocked class is used to make a simple statement atomic session of a variable (the smallest execution unit is not interrupted halfway), providing a way to increment, decrement, exchange, and read values in a thread-safe manner.
For the above example, replace the idx++ with the interlocked.increment (ref IDX);
    • The monitor class is the pure class that implements the lock mechanism, and the lock statement is parsed by the compiler to use the Monitor class.
Lock (obj) {    //synchronized region for obj} is equivalent to Monitor.Enter (obj); Try {    //synchornized region for obj}finally{    Monitor.Exit (obj)}

Use TryEnter to add timeout

1 Objectobj =New Object();2Task.run (() ={3     Lock(obj)4     {5Console.WriteLine ("Lock obj");6Thread.Sleep ( the);7     }8 });9 BOOLb = Monitor.TryEnter (obj, -);Ten if(b) One { A     Try -     { -Console.WriteLine ("Monitor Enter."); the     } -     finally -     { - monitor.exit (obj); +     } - } + Else A { atConsole.WriteLine ("Monitor enter false."); - } -  -Console.readkey ();

In addition, monitor provides a wait method that frees the lock on the object and blocks the current thread until it acquires the lock again.

Provides a pulse method to notify the waiting queue of a change in the state of a thread-locked object; PulseAll notifies all waiting thread object state changes.

  • SpinLock spin Lock, if the system overhead based on object locking (Monitor) is too high for garbage collection, the SpinLock structure can be used. The spinlock structure is useful if you have a large number of locks (for example, each node in the list has a lock) and the lock time is always very short. You should avoid using multiple spinlock structures, and do not invoke any content that might be blocked. SpinLock should be used only for you, so you can improve the performance of your application after you determine it. There's one more thing to watch out forspinlock  is , in order to improve performance. spinlock instance, as the and the instances Inal and the copy) would then be completely independent of one another, which would likely leads to erroneous behavior of T He application. " >  for this reason, you must be very careful not to accidentally replicate  spinlock  instances, because two instances (original items and replicas) are completely independent of each other, this may lead to incorrect behavior of the application. spinlock instance must be passed around, it should is passed by reference rather than by value." >  if  spinlock  must be passed around the instance, it should be passed by reference instead of by value.

    Do not store SpinLock instances in a read-only field.

C # Multithreading series (vi)

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.