栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

C#关于加锁的多线程同步方法的代码规范

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C#关于加锁的多线程同步方法的代码规范

我们在程序开发中,经常会出现多线程中进行同步操作,比如多人抢票,多人抢红包,库存数量的更新,都需要进行局部同步操作。

使用锁对象进行同步访问的几种代码示例进行比较:

1.静态类的静态变量锁,加锁有效 2.局部类成员变量锁,加锁无效【非常严重】! 3.公共类成员变量锁,加锁有效 4.局部类静态变量锁,加锁有效 5.公共类静态变量锁,加锁有效

防止出错的解决方案: 多线程同时调用一个同步方法【需要排队执行的方法】时,为了防止出现不小心出现的【加锁无效】,请将加锁变量设置为静态的【static】

新建.net 4.6.1控制台应用程序【C#】, 新建类GlobalUtil.cs GlobalUtil类源代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace AboutLockDemo
{
    /// 
    /// 公共共享变量 与 加锁、释放锁方法
    /// 
    public class GlobalUtil
    {
        /// 
        /// 共享变量的值
        /// 
        public static int SharedVariable = 0;

        /// 
        /// 复位共享变量的值
        /// 
        public static void ResetSharedVariable() 
        {
            SharedVariable = 0;
        }

        /// 
        /// 添加锁,进入锁
        /// 
        /// 
        public static void EnterLock(ref int lockedValue) 
        {
            bool isWriteLog = false;
            while (Interlocked.Exchange(ref lockedValue, 1) != 0)
            {
                if (!isWriteLog)
                {
                    isWriteLog = true;
                    Console.WriteLine($"【{DateTime.Now.ToString("HH:mm:ss.fff")}】触发多线程同时调用接口");
                }
            }
            Console.WriteLine($"【{DateTime.Now.ToString("HH:mm:ss.fff")}】开始执行同步方法,已添加锁...");
        }

        /// 
        /// 释放锁,解除锁
        /// 
        /// 
        public static void ReleaseLock(ref int lockedValue) 
        {
            Interlocked.Exchange(ref lockedValue, 0);//释放锁
            Console.WriteLine($"【{DateTime.Now.ToString("HH:mm:ss.fff")}】结束执行同步方法,已释放锁...");
        }
    }
}
新建静态类LockedStaticForStaticClass.cs LockedStaticForStaticClass类源代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace AboutLockDemo
{
    /// 
    /// 静态类中使用静态变量锁
    /// 
    public static class LockedStaticForStaticClass
    {
        /// 
        /// 加锁变量
        /// 
        private static int lockedValue = 0;
        /// 
        /// 加锁方法
        /// 
        public static void LockedMethod() 
        {
            GlobalUtil.EnterLock(ref lockedValue);
            GlobalUtil.SharedVariable++;
            Thread.Sleep(new Random(Guid.NewGuid().GetHashCode()).Next(100, 500));
            Console.WriteLine($"【加一】以后当前共享变量的值【{GlobalUtil.SharedVariable}】");
            GlobalUtil.ReleaseLock(ref lockedValue);
        }
    }
}
新建实例化成员变量类LockedMemberForInstanceClass.cs LockedMemberForInstanceClass源程序如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace AboutLockDemo
{
    /// 
    /// 实例化类中使用成员变量锁
    /// 
    public class LockedMemberForInstanceClass
    {
        /// 
        /// 加锁变量
        /// 
        private int lockedValue = 0;
        /// 
        /// 加锁方法
        /// 
        public void LockedMethod()
        {
            GlobalUtil.EnterLock(ref lockedValue);
            GlobalUtil.SharedVariable++;
            Thread.Sleep(new Random(Guid.NewGuid().GetHashCode()).Next(100, 500));
            Console.WriteLine($"【加一】以后当前共享变量的值【{GlobalUtil.SharedVariable}】");
            GlobalUtil.ReleaseLock(ref lockedValue);
        }
    }
}
新建实例化静态成员类LockedStaticForInstanceClass.cs LockedStaticForInstanceClass源程序如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace AboutLockDemo
{
    /// 
    /// 实例化类中使用静态对变量锁
    /// 
    public class LockedStaticForInstanceClass
    {
        /// 
        /// 加锁变量
        /// 
        private static int lockedValue = 0;
        /// 
        /// 加锁方法
        /// 
        public void LockedMethod()
        {
            GlobalUtil.EnterLock(ref lockedValue);
            GlobalUtil.SharedVariable++;
            Thread.Sleep(new Random(Guid.NewGuid().GetHashCode()).Next(100, 500));
            Console.WriteLine($"【加一】以后当前共享变量的值【{GlobalUtil.SharedVariable}】");
            GlobalUtil.ReleaseLock(ref lockedValue);
        }
    }
}
在默认的Program.cs中输入测试代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AboutLockDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("--------------测试几种锁的程序写法以及具体的处理结果--------------");
            TestStaticClassLock();
            TestInstanceLocalClassLock();
            TestInstanceCommonClassLock();
            TestInstanceLocalClassStaticLock();
            TestInstanceCommonClassStaticLock();
            Console.WriteLine("多线程同时调用一个同步方法【需要排队执行的方法】时,为了防止出现不小心出现的【加锁无效】,请将加锁变量设置为静态的【static】,形如:");
            Console.WriteLine("                  private static int lockedValue = 0;");
            Console.ReadLine();
        }

        /// 
        /// 静态类变量,加锁有效
        /// 
        static void TestStaticClassLock() 
        {
            GlobalUtil.ResetSharedVariable();
            List tasks = new List();
            for (int i = 0; i < 3; i++)
            {
                int taskIndex = i;
                tasks.Add(Task.Run(() =>
                {
                    Console.WriteLine($"开始执行线程【{taskIndex + 1}】...");
                    LockedStaticForStaticClass.LockedMethod();
                }));
            }
            Task.WaitAll(tasks.ToArray());
            Console.WriteLine("--------------静态类的静态变量锁,加锁有效--------------");
        }

        /// 
        /// 局部类成员变量锁,导致的结果是加锁无效【无法加锁的代码】
        /// 
        static void TestInstanceLocalClassLock() 
        {
            GlobalUtil.ResetSharedVariable();
            List tasks = new List();
            for (int i = 0; i < 3; i++)
            {
                int taskIndex = i;
                tasks.Add(Task.Run(() =>
                {
                    Console.WriteLine($"开始执行线程【{taskIndex + 1}】...");
                    //局部变量
                    LockedMemberForInstanceClass instanceObject = new LockedMemberForInstanceClass();
                    instanceObject.LockedMethod();
                }));
            }
            Task.WaitAll(tasks.ToArray());
            Console.WriteLine("--------------局部类成员变量锁,加锁无效【非常严重】!--------------");
        }

        /// 
        /// 公共类成员变量锁,加锁有效
        /// 
        static void TestInstanceCommonClassLock()
        {
            GlobalUtil.ResetSharedVariable();
            //公共变量
            LockedMemberForInstanceClass instanceObject = new LockedMemberForInstanceClass();
            List tasks = new List();
            for (int i = 0; i < 3; i++)
            {
                int taskIndex = i;
                tasks.Add(Task.Run(() =>
                {
                    Console.WriteLine($"开始执行线程【{taskIndex + 1}】...");
                    instanceObject.LockedMethod();
                }));
            }
            Task.WaitAll(tasks.ToArray());
            Console.WriteLine("--------------公共类成员变量锁,加锁有效--------------");
        }

        /// 
        /// 局部类静态变量锁,加锁有效
        /// 
        static void TestInstanceLocalClassStaticLock()
        {
            GlobalUtil.ResetSharedVariable();
            List tasks = new List();
            for (int i = 0; i < 3; i++)
            {
                int taskIndex = i;
                tasks.Add(Task.Run(() =>
                {
                    Console.WriteLine($"开始执行线程【{taskIndex + 1}】...");
                    //局部变量
                    LockedStaticForInstanceClass instanceObject = new LockedStaticForInstanceClass();
                    instanceObject.LockedMethod();
                }));
            }
            Task.WaitAll(tasks.ToArray());
            Console.WriteLine("--------------局部类静态变量锁,加锁有效--------------");
        }

        /// 
        /// 公共类静态变量锁,加锁有效
        /// 
        static void TestInstanceCommonClassStaticLock()
        {
            GlobalUtil.ResetSharedVariable();
            //公共类变量
            LockedStaticForInstanceClass instanceObject = new LockedStaticForInstanceClass();
            List tasks = new List();
            for (int i = 0; i < 3; i++)
            {
                int taskIndex = i;
                tasks.Add(Task.Run(() =>
                {
                    Console.WriteLine($"开始执行线程【{taskIndex + 1}】...");
                    instanceObject.LockedMethod();
                }));
            }
            Task.WaitAll(tasks.ToArray());
            Console.WriteLine("--------------公共类静态变量锁,加锁有效--------------");
        }
    }
}
程序运行如图:

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1022692.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号