• “锁定”语句(C# 参考)


    lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。 此语句的形式如下:

    复制

    Object thisLock = new Object();

    lock (thisLock)

    {

        // Critical code section.}

    lock 关键字可确保当一个线程位于代码的临界区时,另一个线程不会进入该临界区。 如果其他线程尝试进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。

    lock 关键字在块的开始处调用 Enter,而在块的结尾处调用 Exit

    通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。 常见的结构 lock (this)lock (typeof (MyType)) lock ("myLock") 违反此准则:

    ·         如果实例可以被公共访问,将出现 lock (this) 问题。

    ·         如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。

    ·         由于进程中使用同一字符串的任何其他代码都将共享同一个锁,所以出现 lock(“myLock”) 问题。

    最佳做法是定义 private 对象来锁定, private static 对象变量来保护所有实例所共有的数据。

    示例

    下面演示在 C# 中使用未锁定的线程的简单示例。

    C#

     

        //using System.Threading;

     

        class ThreadTest

        {

            public void RunMe()

            {

                Console.WriteLine("RunMe called");

            }

     

            static void Main()

            {

                ThreadTest b = new ThreadTest();

                Thread t = new Thread(b.RunMe);

                t.Start();

            }

        }

        // Output: RunMe called

     

     

     

    下例使用线程和 lock 只要 lock 语句存在,语句块就是临界区并且 balance 永远不会是负数。

    C#

        // using System.Threading;

        class Account

        {

            private Object thisLock = new Object();

            int balance;

            Random r = new Random();

            public Account(int initial)

            {

                balance = initial;

            }

            int Withdraw(int amount)

            {

                // This condition will never be true unless the lock statement

                // is commented out:

                if (balance < 0)

                {

                    throw new Exception("Negative Balance");

                }

                // Comment out the next line to see the effect of leaving out

                // the lock keyword:

                lock (thisLock)

                {

                    if (balance >= amount)

                    {

                        Console.WriteLine("Balance before Withdrawal : " + balance);

                        Console.WriteLine("Amount to Withdraw        : -" + amount);

                        balance = balance - amount;

                        Console.WriteLine("Balance after Withdrawal : " + balance);

                        return amount;

                    }

                    else

                    {

                        return 0; // transaction rejected

                    }

                }

            }

            public void DoTransactions()

            {

                for (int i = 0; i < 100; i++)

                {

                    Withdraw(r.Next(1, 100));

                }

            }

        }

        class Test

        {

            static void Main()

            {

                Thread[] threads = new Thread[10];

                Account acc = new Account(1000);

                for (int i = 0; i < 10; i++)

                {

                    Thread t = new Thread(new ThreadStart(acc.DoTransactions));

                    threads[i] = t;

                }

                for (int i = 0; i < 10; i++)

                {

                    threads[i].Start();

                }

            }

        }

  • 相关阅读:
    DRF项目之视图获取路径参数
    DRF项目之层级关系
    DRF项目之序列化器和视图重写方法的区别
    DRF项目之自定义分页器
    DRF项目之实现用户密码加密保存
    DRF项目之通过业务逻辑选择数据集和序列化器
    DRF项目之自定义JWT认证响应数据
    PIP一次性导入所有环境和指定镜像源
    DRF项目之JWT认证方式的简介及使用
    DRF项目之解决浏览器同源策略问题
  • 原文地址:https://www.cnblogs.com/gsk99/p/1904568.html
Copyright © 2020-2023  润新知