- Multithreading in C# 5.0 Cookbook
- Eugene Agafonov
- 349字
- 2021-07-21 18:10:01
Performing basic atomic operations
This recipe will show you how to perform basic atomic operations on an object to prevent the race condition without blocking threads.
Getting ready
To step through this recipe, you will need Visual Studio 2012. There are no other prerequisites. The source code for this recipe could be found at 7644_Code\Chapter2\Recipe1
.
How to do it...
To understand the basic atomic operations, perform the following steps:
- Start Visual Studio 2012. Create a new C# Console Application project.
- In the
Program.cs
file, add the followingusing
directives:using System; using System.Threading;
- Below the
Main
method, add the following code snippet:static void TestCounter(CounterBase c) { for (int i = 0; i < 100000; i++) { c.Increment(); c.Decrement(); } } class Counter : CounterBase { private int _count; public int Count { get { return _count; } } public override void Increment() { _count++; } public override void Decrement() { _count--; } } class CounterNoLock : CounterBase { private int _count; public int Count { get { return _count; } } public override void Increment() { Interlocked.Increment(ref _count); } public override void Decrement() { Interlocked.Decrement(ref _count); } } abstract class CounterBase { public abstract void Increment(); public abstract void Decrement(); }
- Inside the
Main
method, add the following code snippet:Console.WriteLine("Incorrect counter"); var c = new Counter(); var t1 = new Thread(() => TestCounter(c)); var t2 = new Thread(() => TestCounter(c)); var t3 = new Thread(() => TestCounter(c)); t1.Start(); t2.Start(); t3.Start(); t1.Join(); t2.Join(); t3.Join(); Console.WriteLine("Total count: {0}", c.Count); Console.WriteLine("--------------------------"); Console.WriteLine("Correct counter"); var c1 = new CounterNoLock(); t1 = new Thread(() => TestCounter(c1)); t2 = new Thread(() => TestCounter(c1)); t3 = new Thread(() => TestCounter(c1)); t1.Start(); t2.Start(); t3.Start(); t1.Join(); t2.Join(); t3.Join(); Console.WriteLine("Total count: {0}", c1.Count);
- Run the program.
How it works...
When the program runs, it creates three threads that will execute a code in the TestCounter
method. This method runs a sequence of increment/decrement operations on an object. Initially, the Counter
object is not thread-safe and we get a race condition here. So in the first case, a counter value is not deterministic. We could get a zero value; however, if you run the program several times, you will eventually get some incorrect nonzero result.
In Chapter 1, Threading Basics, we resolved this problem by locking our object, causing other threads to block while one thread gets the old counter value, then computes and assigns a new value to the counter. However, if we execute this operation in such a way, it cannot be stopped midway; we would achieve the proper result without any locking with the help of the Interlocked
construct. It provides the atomic methods Increment
, Decrement
, and Add
for basic math, and it helps us to write the Counter
class without the use of locking.
- Java語言程序設(shè)計(jì)
- ASP.NET Core:Cloud-ready,Enterprise Web Application Development
- JBoss Weld CDI for Java Platform
- 自己動(dòng)手寫Java虛擬機(jī)
- 趣學(xué)Python算法100例
- Rust Cookbook
- 算法訓(xùn)練營:提高篇(全彩版)
- 利用Python進(jìn)行數(shù)據(jù)分析(原書第3版)
- 數(shù)據(jù)結(jié)構(gòu)習(xí)題解析與實(shí)驗(yàn)指導(dǎo)
- Django 3.0入門與實(shí)踐
- 實(shí)驗(yàn)編程:PsychoPy從入門到精通
- HTML5+CSS+JavaScript深入學(xué)習(xí)實(shí)錄
- Visual FoxPro數(shù)據(jù)庫程序設(shè)計(jì)
- Learning Yeoman
- Oracle 11g寶典