• ag百家乐两个平台对打可以吗 并发编程 - 线程同步(六)之锁lock

    发布日期:2024-03-01 09:24    点击次数:168

    通过前边对Interlocked类的学习,驯顺大众对线程同步机制有了更深的一语气,今天咱们将陆续需要另一种同步机制——锁lock。

    lock是C#话语中的重要字,是线程同步机制的一种毛糙的互斥锁圮绝方法,它不错保证在统一时辰唯唯一个线程能够访谒被锁定的代码块。其责任旨趣也很毛糙,等于通过lock创建一个互斥锁,当一个线程得到到此互斥锁则此线程不错参预被lock保护的代码块,同期其他线程将被结巴无法参预此代码块,直至第一个线程开释此互斥锁,其他线程才不错得到此互斥锁并参预代码块。

    lock的使用也卓绝毛糙,语法如下:

    lock (obj)

    {

    //线程不安全的代码块

    }

    固然lock使用起来毛糙浅近,可是使用方法不正确也很容易产生各式奇奇怪怪的问题。

    01、幸免锁定this

    这种使用方法会导致两个问题:

    1.不行控性:lock(this)锁定的鸿沟是悉数这个词实例,这也就意味着其他线程不错通过该实例中的其他圭表访谒该锁,进而酿成一个实例中多个使用lock(this)的圭表之前彼此影响。

    2.外部可见性:this示意现时实例的援用,它是大众的,因此外部代码也不错访谒,这也就意味着外部代码不错通过lock(实例)访谒lock(this)锁,从而使同步机制失去遗弃。

    底下咱们平直看代码:

    咱们望望代码实施效果:

    这里例子不错很好的讲解lock(this)代理的问题,蓝本不错三个线程并发实施的三段代码,因为使用了统一个锁,导致三个线程只可执法实施。其中Method1和Method2体现了统一实例内圭表彼此影响,Method3和Method1、Method2体现了因为交流实例导致实例里面圭表和实例外部圭表彼此影响。

    02、幸免锁定大众对象

    这种使用方法会导致两个问题:

    1.全局影响:大众对象,突出是 public static 对象,很约略率会被多个类,致使多个模块援用,2022年AG百家乐假不假因此锁定大众对象很可能导致全局鸿沟内的同步,大大增多了死锁、竞争条款的产生的风险。

    2.不行探讨性:因为大众对象对全局可访谒,因此如果其他模块锁定此大众对象,则当出现问题时将难以摈弃调试问题。

    看底下代码:

    在望望实施效果:

    不错发现因为锁定了统一个大众对象,导致两个不同线程的不同实例,也曾产生彼此争抢锁的问题。

    03、幸免锁定字符串

    在C#中,字符串因其不行变性和字符串池的原因,在悉数这个词要津中一个字符串一朝创建就不会编削,如果对其修改则产生新的字符串对象,而原字符串对象保抓不变;同期如果创建两个交流本色的字符串,则它们分享统一个内存地址。

    这就导致锁定字符串极其危急尤其危急,因为悉数这个词要津中任何给定字符串齐唯唯一个实例,而在悉数这个词要津中唯独锁定交流本色的字符串齐会酿成竞争条款。

    咱们望望实施效果:

    不错发现固然在两个类均永别使用了两个字符串“abc”,但关于悉数这个词要津来说它们齐指向了统一个实例,因此共用了一把锁。

    04、留心锁定非readonly对象

    这是因为如果锁对象为非只读对象,就可能发生某个lock代码块中修改锁对象,从而导致

    锁对象变更,进而使得其他线程不错通晓无阻的参预该代码块。

    如下示例:

    再来看实施效果:

    不错发现三个线程险些同期参预,lock压根就莫得起到锁的作用。

    05、留心锁定静态对象

    关于是否需要锁定静态对象取决于你的需求。

    1.如果要在静态圭表中使用lock时,则锁定的对象也必须如若静态对象。

    2.如果但愿类的每个实例齐有沉寂的锁对象,则锁定非静态对象。

    3.如果但愿类的悉数实例分享统一个锁,则锁定静态对象。

    代码示举例下:

    这是因为静态字段是悉数实例分享的,其内存地址在悉数这个词要津的生命周期内是唯一的ag百家乐两个平台对打可以吗,悉数实例访谒统一个内存地址,因此锁定静态对象时要突出留心。