• lock 语句(C# 参考)


    lock 语句(C# 参考)

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

    Object thisLock = new Object();
    lock (thisLock)
    {
    // Critical code section
    }

    有关更多信息,请参见 线程同步(C# 编程指南)

     备注

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

    线程处理(C# 编程指南) 这节讨论了线程处理。

    lock 调用块开始位置的 Enter 和块结束位置的 Exit

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

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

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

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

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

     示例

    下例显示的是在 C# 中使用线程的简单示例。

    // statements_lock.cs
    using System;
    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();
    }
    }

    输出

    RunMe called

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

    // statements_lock2.cs
    using System;
    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();
    }
    }
    }
  • 相关阅读:
    centos中pipelinedb安装及初步使用
    sqlalchemy 的操作
    存储引擎,索引,慢日志,权限管理
    python使用mysql
    mysql数据库查找数据的方法。
    mysql 数据库的基本操作
    epoll 数据库安装以及相关概念
    IO模型,非阻塞IO模型,select实现多路复用
    线程回调,线程中的队列,事件,greenlet模块,gevent模块,自定义补丁, 单线程实现并发,协程
    GIL全局解释器锁,线程池与进程池 同步异步,阻塞与非阻塞,异步回调
  • 原文地址:https://www.cnblogs.com/blsong/p/1642218.html
Copyright © 2020-2023  润新知