zoukankan      html  css  js  c++  java
  • 异步编程之共享对象同步

    当我使用实现异步编程时,大大的提高了,CUP利用率,让前端UI线程能够得到及时的响应.

    但在我们使用时,必须要考虑到线程共享对象的同步问题,否则计算结果将不可控.所以,这里,根据自己的经验,对C#中用于解决线程同步问题简单的总结一下.

    实现线程同有一下几种方式:

    1.lock(Monitor的语法糖) 2.Monitor 3.AutoResetEvent 4.Interlocked(原子操作) 5.SpinLock 6.Semaphore 7.Mutex

    下面直接上代码对几种实现方式的示例:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Threading;
    using System.Runtime.Remoting.Messaging;
    
    namespace ConsoleApplication4
    {
        class Program
        {
            static void Main(string[] args)
            {
                //初始化一个用户,出事账户金额10000元。
                //初始化10个任务,每次调用用户购物事件,扣取随机金额。
               
                var user = new User(10000);
                var tasks = new List<Task>();
                System.Random r = new Random();
                for (int i = 0; i < 10; i++)
                {
                    var t = new Task(() =>
                    {
                        user.Shopping(r.Next(1, 5000));
                    });
                    tasks.Add(t);
                }
                tasks.ForEach(t =>{t.Start();});
    
                Console.ReadKey();
            }
    
    
        }
    
        class User{
    
            //异步编程-控制并发
            //为保证一个公共对象,在同一时刻只有一个线程占有操作。
            //锁实现方式有多种 1.lock(Monitor的语法糖) 2.Monitor 3.AutoResetEvent 4.Interlocked(原子操作) 5.SpinLock 6.Semaphore 7.Mutex
    
            private AutoResetEvent autoResetEvent = new AutoResetEvent(true);
            private int interlocked = 0;
            private SpinLock spinLock = new SpinLock(false);
            private Semaphore semaphore = new Semaphore(0, 1);
            private Mutex mutex = new Mutex();
    
            private decimal Amount; //账户金额
    
            /// <summary>
            /// 构造函数,初始化账户金额
            /// </summary>
            /// <param name="amount"></param>
            public User(decimal amount)
            {
                this.Amount = amount;
            }
    
            /// <summary>
            /// 购物消费
            /// </summary>
            /// <param name="money"></param>
            public void Shopping(decimal money) {
                
                //1.lock示例(只能锁引用对象)
                lock (this){
                    UpdateAmount(money);
                }
    
                //2.Monitor(只能锁引用对象)
                try{
                    Monitor.Enter(this);//加锁
                    UpdateAmount(money);
                }
                finally {
                    Monitor.Exit(this);//释放锁
                }
    
    
                //3.AutoResetEvent
                //通知正在等待的线程已发生事件
                try
                {
                    autoResetEvent.WaitOne();//加锁
                    UpdateAmount(money);
                }
                finally {
                    autoResetEvent.Set();//释放锁
                }
    
                //4.Interlocked (自旋锁)
                //为多个线程共享的变量提供原子操作。
                //
                try
                {
                    while (1 == Interlocked.Exchange(ref interlocked, 1))
                    {
                        //如果值为1,则一直自旋等待.
                    }
                    UpdateAmount(money);
                }
                finally
                {
                    Interlocked.Exchange(ref interlocked, 0);
                }
               
                //5.SpinLock
                //提供一个相互排斥锁基元,在该基元中,尝试获取锁的线程将在重复检查的循环中等待,直至该锁变为可用为止.
                //锁定一个布尔类型对象,初始值必须为false
                bool spinLocker = false;
                try
                {
                   
                    spinLock.Enter(ref spinLocker);//加锁
                    UpdateAmount(money);
                }
                finally
                {
                    if(spinLocker)
                       spinLock.Exit();//释放锁
                }
    
                //6.Semaphore(信号)
                //限制可同时访问某一资源或资源池的线程数
                try
                {
    
                    semaphore.WaitOne();//加锁
                    UpdateAmount(money);
                }
                finally
                {
                    semaphore.Release(1);//释放锁
                }
    
                //7.Mutex
                //可用于线程,还可用于进程间同步的同步基元。
                try
                {
                    mutex.WaitOne();//加锁
                    UpdateAmount(money);
                }
                finally
                {
                    mutex.ReleaseMutex();//释放锁
                }
            }
            /// <summary>
            /// 更新账户
            /// </summary>
            /// <param name="money"></param>
            private void UpdateAmount(decimal money) {
                if (this.Amount < money)
                {
                    //账户金额不足,显示账户金额。
                    Console.WriteLine("本次消费:" + money + ",余额不足!当前余额:" + this.Amount);
                }
                else {
                    //账户金额充足,更新账户金额,显示账户金额。
                    Console.WriteLine(this.Amount + "-" + money + " = " + (this.Amount - money));
                    this.Amount -= money;
                }
            }
        }
    }
  • 相关阅读:
    关于并发量的简单计算公式
    kbmmw中向服务器端传递对象的一种简单方式
    tms web core 里面调用pascal 过程。
    tms web core 通过URL 传递参数
    tms web core 与 kbmmw 第一次亲密接触
    kbmmw 的HTTPSmartService 上传文件到服务器端
    kbmmw 中的进程管理小工具
    kbmmw 5.06.20 发布
    kbmmw ORM 对象定义语法简析
    kbmmw 5.06.00 beta 发布
  • 原文地址:https://www.cnblogs.com/paulcode/p/10076221.html
Copyright © 2011-2022 走看看