zoukankan      html  css  js  c++  java
  • lock关键字理解

    >可以把lock关键字可以看成

    try{
        Monitor.Enter(x);
        //..
    }
    finally{
        Monitor.Exit(x);
    }

    这样子的结构,当然使用lock关键字更方便

    >容易混淆的lock(对象) 

    这个里面的锁对象很容易搞混淆,下面区别一下lock(this),lock(typeof(tt)),lock("a")

    1)lock(this) 下面代码

    public class A{
        public void Foo(){
            lock(this){
                //...
            }
        }
    }

    如果是A的同一个对象,开多个线程调用Foo方法,是没有问题的,如下面代码

    A a=new A();
    int count=10;
    while(count-->0){
        Task.Factory.StartNew(a.Foo);
    }

    但是下面代码就会出错

    int count=10
    while(count-->0){
        A a=new A();
        Task.Factory.StartNew(a.Foo);
    }

    因为这里lock的是A的对象本身,所以等于没有锁.其实在代码多数情况应该是后面一种,因为多个线程同一般情况下来自不同调用同一个类里的方法,比如多个用户同时在线操作.

    2)lock("a"),lock((object)1)  其实这里不是一类,是两类

    把这种看成lock一个值吧.这种在自己写测试的时候看不出效果,像lock("a")这个加到上面个例子里是实全可以实现效果的,因为C#对字符串做了缓存,只要在这个驻留池里面有的字符,它是不会再创建对象的,比如 string a="a";string b="a";这两句运行后a,b两个引用指向同一个字符串.所以我们的lock("a")永远都会有锁定效果,但是就会带一个问题 ,如果有两个方法这样写就会出问题了,也就是运行另一个方法时把运行当前这个方法线程也阻塞了.
    而lock(object)1这个就是永远都没有效果的做法,因为每次都是int类型的一个装箱,不同的对象.

    3)lock(typeof(tt))
    因为typeof(tt)得出的对象引用都是同一个引用,所以同刚才那个lock("a")是一样的效果

    建议的使用是单独用一个成员来做为锁对象就可以解决上面的问题 

  • 相关阅读:
    BZOJ 1101 莫比乌斯函数+分块
    BZOJ 2045 容斥原理
    BZOJ 4636 (动态开节点)线段树
    BZOJ 2005 容斥原理
    BZOJ 2190 欧拉函数
    BZOJ 2818 欧拉函数
    BZOJ 3123 主席树 启发式合并
    812. Largest Triangle Area
    805. Split Array With Same Average
    794. Valid Tic-Tac-Toe State
  • 原文地址:https://www.cnblogs.com/gw2010/p/3465853.html
Copyright © 2011-2022 走看看