This article is a mirror article of machine translation, please click here to jump to the original article.

View: 46741|Reply: 7

[Source] Volatile vs. Interlocked vs. lock

[Copy link]
Posted on 8/27/2018 2:40:35 PM | | |
Let's say there is a class that contains a public int counter field that can be accessed by multiple threads, and this number will only increase or decrease.

When adding this field, which of the following schemes should be used, and why?

  • lock(this.locker) this.counter++;
  • Interlocked.Increment(ref this.counter);
  • Change the access modifier of counter to public volatile


Worst (none of them actually work)

Change the access modifier of counter to public volatile

This approach is actually not secure at all, and the point about volatile is that multiple threads running on multiple CPUs buffer data and rearrange executed instructions.

If it is non-volatile, when CPU A increases by a value, CPU B needs to wait a while to see the increased value, which can lead to problems.

If it's volatile, it ensures that both CPUs see the same value at the same time. But it doesn't avoid cross-cutting read and write operations.

Adding value to a variable actually takes three steps

1. Reading, 2. Add 3. Write

Suppose thread A reads the value of counter as 1 and is not ready to increase, then thread B also reads the value of counter as 1, and then both threads start to perform incremental and write operations. The value of the final counter is 2. This is not right, both threads have done an increase operation, and the correct result should be 3. So labeling it as volatile is simply unsafe.

It's better

lock(this.locker) this.counter++;

This way it's safe (remember to lock everywhere you want to access this.counter, of course). It prevents any other thread from executing the locked code. And it also prevents the multi-CPU instruction sequencing problem mentioned above. The problem is that lock is slow in performance, and if you use lock in other unrelated places, it can block your other threads.

Best

Interlocked.Increment(ref this.counter);

This is safe and very efficient. It performs read, increase, write three operations in one atom without being interrupted in the middle. Because it doesn't affect other code, you don't need to remember locks elsewhere. And it's also very fast (as MSDN says, on today's CPUs, it's often just an instruction).

But I'm not entirely sure if it can also solve the CPU's instruction ordering problem, or if it needs to be used in conjunction with volatile and this increment.

Supplement: What problems does volatile solve well?

Since volatile can't prevent multithreading, what can it do? A good example is that you have two threads, one always writes to a variable, let's say this variable is queneLength, and the other always reads data from this variable. If queueLenght is not volatile, thread A may read 5 times, but thread B may see delayed data, or even data in the wrong order. One solution is to use lock, but in this case you can also use volatile. This ensures that thread B always sees the latest data written by thread A, but this logic only works if you don't read it when you write it, and if you don't write it when you read it. Once multiple threads want to do read-modify-write operations, you need to use Interlocked or lock.





Previous:Java MD5 encryption method
Next:Linq implements not in and in conditional queries in SQL
Posted on 8/29/2018 4:21:42 PM |
Hello, the code you did earlier that combines highcharts stacked histograms and drillable histograms? I would like to ask if you can send a code that can be edited on the https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light interface?
Posted on 8/29/2018 4:22:13 PM |
The whole network is just your resource.
Posted on 8/29/2018 4:22:55 PM |
Because the previous 90 years ago could not leave a message. so
Posted on 8/29/2018 4:40:40 PM |
Is it convenient to add a contact information? Consult with you
 Landlord| Posted on 9/15/2018 1:10:16 PM |
private static int safeInstanceCount = 0; Operate with atoms
System.Threading.Interlocked.Increment(ref safeInstanceCount); Self-increase 1
System.Threading.Interlocked.Decrement(ref safeInstanceCount); Self-minus 1
Posted on 5/21/2020 4:43:54 PM |
Support the owner to share
 Landlord| Posted on 6/11/2020 3:00:16 PM |
1. Concept

In a multi-threaded environment, operations that are not interrupted by thread scheduling mechanisms; Once this operation starts, it runs until the end, without any context switch (switching to another thread) in between.

2. Class

System.Threading.Interlocked static class

3. Commonly used functions (see the rest)

1.public static int Decrement(ref int location); Decrin the value of the specified variable in the form of an atomic operation and store the result

Equivalent to lock(obj){i--; }

2.public static int Increment(ref int location); Increment the value of the specified variable in the form of an atomic operation and store the result

Equivalent to lock(obj){i++; }
Disclaimer:
All software, programming materials or articles published by Code Farmer Network are only for learning and research purposes; The above content shall not be used for commercial or illegal purposes, otherwise, users shall bear all consequences. The information on this site comes from the Internet, and copyright disputes have nothing to do with this site. You must completely delete the above content from your computer within 24 hours of downloading. If you like the program, please support genuine software, purchase registration, and get better genuine services. If there is any infringement, please contact us by email.

Mail To:help@itsvse.com