Interlocked实现线程的同步与互斥

一、描述

MSDN :为多个线程共享的变量提供原子操作。通过System.Threading命名空间的Interlocked类控制计数器,从而实现线程的同步与互斥。Iterlocked类的部分方法如下表:

 

二、原理

当线程正在更新可被其他线程访问的变量时,或者当两个线程同时在不同的处理器上执行时。确保 此类的成员不会引发异常。

 在大多数计算机上,递增变量不是原子操作,需要执行以下步骤:

  1. 将实例变量中的值加载到寄存器中。

  2. 递增或减小值。

  3. 将值存储在实例变量中。

如果不使用 Increment 和 Decrement,则在执行前两个步骤后,可以抢占线程。 然后,另一个线程可以执行所有三个步骤。 当第一个线程继续执行时,它将覆盖实例变量中的值,并且由第二个线程执行的增量或减量的影响将丢失。

Add 方法以原子方式将整数值添加到整数变量中,并返回变量的新值。

Exchange 方法以原子方式交换指定变量的值。 

CompareExchange 方法组合了两个操作:比较两个值,并根据比较结果将第三个值存储在一个变量中。 比较和交换操作以原子操作的方式执行。

三、实例

使用Interlocked.Exchange实现线程的互斥

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace 测试interlock
{
    class Program
    {
        //0 for false, 1 for true.
        private static int usingResource = 0;

        private const int numThreadIterations = 5;

        /// <summary>
        /// 创建线程的个数
        /// </summary>
        private const int numThreads = 5;

        static void Main()
        {
            Thread myThread;
            Random rnd = new Random();

            for (int i = 0; i < numThreads; i++)
            {
                myThread = new Thread(new ThreadStart(MyThreadProc));
                myThread.Name = String.Format("Thread{0}", i + 1);
                Thread.Sleep(rnd.Next(0, 1000)); //Wait a random amount of time before starting next thread.
                myThread.Start();
            }
            Console.ReadKey();
        }

        private static void MyThreadProc()
        {
            for (int i = 0; i < numThreadIterations; i++)
            {
                UseResource();

                Thread.Sleep(1000);   //Wait 1 second before next attempt.
            }
        }

        /// <summary>
        /// 一个简单方法,模拟线程竞争使用临界资源
        /// </summary>
        /// <returns></returns>
        static bool UseResource()
        {

            if (0 == Interlocked.Exchange(ref usingResource, 1)) //将usingResource设为1,但返回原始值0
            {
                Console.WriteLine("{0} acquired the lock", Thread.CurrentThread.Name);

                Thread.Sleep(500);   //模拟一些操作

                Console.WriteLine("{0} exiting lock", Thread.CurrentThread.Name);

                Interlocked.Exchange(ref usingResource, 0);  //Release the lock
                return true;
            }
            else
            {
                Console.WriteLine("   {0} was denied the lock", Thread.CurrentThread.Name);
                return false;
            }
        }
    }
}

 

 

参考:

https://www.cnblogs.com/yy1234/p/11159177.html

https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.interlocked?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query%3FappId%3DDev15IDEF1%26l%3DZH-CN%26k%3Dk(System.Threading.Interlocked);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5.2);k(DevLang-csharp)%26rd%3Dtrue&view=netcore-3.1

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值