C#spinwait and volatile a little refresher

Source: Internet
Author: User
Tags switches volatile

Today see concurrentqueue<t> source found inside incredibly didn't use lock, I remember concurrentdictionary inside is lock, lock is a dictionary inside every key, But Concurrentqueue<t> 's thread safety is actually implemented with the SpinWait object and the volatile keyword, so review it and go directly to code

 classTest {/*Volatile is used in multi- threaded environments, when a variable is defined as volatile, reading the value of the variable is read from the Momery and not from the cache every time.        This is done to ensure that the information that reads the variable is up-to-date, regardless of how other threads update the variable.        The volatile modifier is typically used for fields that are accessed by multiple threads but do not use the lock statement to serialize access.        The volatile keyword can be applied to the following types of fields: reference types. Pointer type (in an unsafe context). Note that although the pointer itself can be mutable, the object it points to cannot be mutable.        In other words, you cannot declare a pointer to a mutable object.        types, such as sbyte, Byte, short, ushort, int, uint, char, float, and bool.        An enumeration type that has one of the following base types: Byte, sbyte, short, ushort, int, or UINT.        A generic type parameter that is known to be a reference type.        IntPtr and UIntPtr. mutable keywords can only be applied to class or struct fields.        You cannot declare a local variable as volatile. */        Static volatile BOOL_iscompleted =false; Static voidusermodewait () { while(!_iscompleted) {Console.Write ("②.");            } Console.WriteLine (); Console.WriteLine ("③ waiting to complete"); }        Static voidhybridspinwait () {/*Spin waits for a lightweight synchronization type (struct) that provides support for spin-based waits. SpinWait is only useful in multi-core processors.            Under a single processor, self-rotation takes up CPU time, but nothing happens. SpinWait is not designed to allow multiple tasks or threads to be used concurrently.                       Therefore, if more than one task or thread spins through the SpinWait method, then each task or thread should use its own spinwait instance. */            varW =NewSpinWait ();  while(!_iscompleted) {                //performs a single spin. w.spinonce (); /*determines whether the next call to Spinwait.spinonce () triggers a context switch and kernel conversion.                It is known by the Nextspinwillyield Property code that if SpinWait is running on a single-core computer, it is always context-switched (yielding the processor). SpinWait is more than just an empty loop. It has been carefully implemented to provide the correct rotation behavior for general situations to avoid the high cost of context switches and kernel transitions required for kernel events, to initiate context switches on its own when the rotation time is long enough, and spinwait even to generate a thread's time slice on a multicore computer (threa                D.yield ()) to prevent a waiting thread from blocking a high-priority thread or garbage collector thread. */Console.WriteLine ("whether to trigger context switches and kernel conversions:"+W.nextspinwillyield); } Console.WriteLine ("③ waiting to complete"); }         Public Static voidruntest () {varT1 =NewThread (usermodewait); vart2 =NewThread (hybridspinwait); Console.WriteLine ("① running user mode wait"); T1.            Start (); //suspends the currently executing runtest () method thread for the specified time. Let the t1 thread execute the output ②.Thread.Sleep (1); _iscompleted=true; //blocks the current thread for a specified timeThread.Sleep (Timespan.fromseconds (1)); _iscompleted=false; Console.WriteLine ("① running mixed spinwait construction wait"); T2.            Start (); Thread.Sleep (5); _iscompleted=true;        Console.readkey (); }    }

Find a description of Java on the Internet

I'm afraid it's easiest to explain the difference between volatile and synchronized. Volatile is a variable modifier, while synchronized acts on a code or method; Look at the following three-sentence get code:

    1. i nt i1;               int geti1 ()  {return i1;}
    2. volatile int i2;  int geti2 ()   {return i2;}
    3. int i3;               synchronized int geti3 ()  {return i3;}

Geti1 () Gets the number i1 stored in the current thread. Multiple threads have multiple copies of I1 variables, and these i1 can differ from each other. In other words, another thread may have changed the I1 value within its thread, and this value can be different from the I1 value in the current thread. In fact, Java has an idea called the "main" memory area, where the variable's current "exact value" is stored. Each thread can have its own copy of the variable, and this variable copy value can be different from the "main" memory area. So there is actually a possibility that the I1 value in the "main" memory area is 1, the I1 value in thread 1 is 2, and the I1 value in thread 2 is 3--that the threads 1 and 2 have changed their respective i1 values, and this change has not yet passed to the "main" memory area or other threads.
and Geti2 () gets the i2 value of the "primary" memory area. Variables modified with volatile do not allow a copy of a variable that differs from the "main" memory area. In other words, a variable has to be synchronized in all threads after a volatile modification; any thread changes its value, and all other threads get the same value immediately. As a matter of course, volatile-modified variables are accessed more often than normal variables because the thread has its own variable copy that is more efficient.
Since the volatile keyword has realized the synchronization of data between threads, what synchronized do? Hehe, there are two different points between them. First, the synchronized obtains and releases the monitor-if two threads use the same object lock, the monitor can force the code block to be executed by only one thread at a time-a well-known fact. However, synchronized also synchronizes memory: in fact, synchronized synchronizes the entire thread's memory in the "primary" memory area. Therefore, the Execute Geti3 () method does the following steps:
1. The thread requests to obtain an object lock that monitors the This object (assuming it is not locked, otherwise the thread waits until the lock is released)
2. Thread memory data is eliminated from the "main" memory area (Java Virtual function optimization This step ...)  [I don't know how to express it, Khan])
3. Code block is executed
4. Any change to a variable can now be safely written to the "main" memory area (although the Geti3 () method does not change the value of the variable)
5. Thread release Monitoring object locks on this object
So volatile is simply synchronizing the value of a variable between the thread memory and the "primary" memory, while the synchronized synchronizes the values of all variables by locking and unlocking a monitor. Obviously synchronized consumes more resources than volatile.

A more popular explanation:

volatile literal meaning when variable, unstable. This is almost understandable in C #.

When the compiler optimizes the code, it may put the code that is used frequently in the cache, and then the next call reads the cache directly instead of the memory, which greatly improves efficiency. But the problem is coming along.

In a multithreaded program, if a variable is placed in the cache, and another thread changes the value of the variable, then this thread cannot know the change. It may read the data in the cache directly. Unfortunately, the data in the cache is out of date, and the stale dirty data is being read. There will be a bug.

Declaring variables with volatile can solve this problem. A variable declared with a volatile is the equivalent of telling the compiler that I don't write this variable to the cache because the variable is likely to change.

C#spinwait and volatile a little refresher

Related Article

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.