我在web程序里用了多线程我用lock来同步刚开始申明了一个全局私有静态变量
 private static string ss = "";然后在需要同步的地方用locklock (ss)
{
   //1000000次循环,写同一个文件
}我开了几个浏览器,同时访问这个程序我发现这个时候不会出现多个文件被占用的错误然后我把static去掉,改成private string ss = "";我开了几个浏览器,同时访问这个程序我发现这个时候也不会出现多个文件被占用的错误
然后我把lock都去掉,这个时候就出现文件被占用的错误了我有点疑问,不同的浏览器,访问程序时,不是都会实例化页面类吗?如果是申明私有非静态变量.那么不同的浏览器进程lock的是不同的ss啊为什么这个时候不会出现文件被占用的异常呢?

解决方案 »

  1.   

    lock的是不同的ss也是lock啊,怎么了?
      

  2.   

    如果lock了不同的ss那么对于不同的用户在访问这个页面的时候,他们不一定能同步啊因为一个用户和另外一个用户lock的ss根本不是一个啊
      

  3.   

    呵呵。楼主不错,发现了这个问题。明白线程的拘留池你就能明白这个问题了。[MSDN]
    公共语言运行库通过维护一个表来存放字符串,该表称为拘留池,它包含程序中以编程方式声明或创建的每个唯一的字符串的一个引用。因此,具有特定值的字符串的实例在系统中只有一个。所以,所有的ss=""指向的对象都是一个。那么你应该就可以理解了。
      

  4.   

    lock是针对堆中的对象,而不是引用,这也是不能lock值类型的原因。所有引用类型在声明时会额外声明两个东西,一个是同步索引,一个同方法表索引。
    而值类型没有。所以只要指向的对象是一个就OK了。
      

  5.   

    www_123du_com(鼠·神·泪) ( ) 信誉:100    Blog 能浅显一点吗?有点深傲
      

  6.   

    呵,就是说,private string ss = "";这句所有的ss指向的是同一个对象。这是.NET为字符串对象作的一个特殊处理,JAVA也一样。
    即所有静态声明的值一样的字符串都指向同一个对象,这个对象被存放在系统表里。
      

  7.   

    明白楼主的疑问了,
    要验证www_123du_com(鼠·神·泪)的说法,楼主把
     private string ss = "";改为
     private object ss = new object();然后lock(ss)试试会不会出错,就知道string是不是
    特殊的那一个了.
    期待测试结果
      

  8.   

    明白楼主的疑问了,
    要验证www_123du_com(鼠·神·泪)的说法,楼主把
     private string ss = "";改为
     private object ss = new object();然后lock(ss)试试会不会出错,就知道string是不是
    特殊的那一个了.
    期待测试结果
    -----------------------------------------------------------------
    换成object后出错了难道真是string 是特殊的?????
      

  9.   

    [STAThread]
            public static void Main(string[] args)
            {
                string str1 = "abcd";
                string str2 = "abcd";
                Console.WriteLine(object.ReferenceEquals(str1, str2));
                str1 = "ff";
                Console.WriteLine(object.ReferenceEquals(str1, str2));
                str1 = "abcd";
                Console.WriteLine(object.ReferenceEquals(str1, str2));
                Console.ReadLine();
            }
     
      

  10.   

    class A
    {
    private string ss = "";
    }
    A instance1 = new A();
    A instance2 = new A();
    instance1和instance2的ss值相同,所以指向同一对象,则锁定ss效果同锁定静态对象.class A
    {
    private string ss = "";
    public A(string s)
    {
    ss = s;
    }
    }
    如果这样,为ss指定不同值,就不能lock ss了
      

  11.   

    原来string都还要pool,以前还不知道。改为ss = DateTime.Now.ToString()应该就锁不住了。
      

  12.   

    因为这点,所以尽量不要锁string,以免两个互不相关的线程刚好锁了同一个string对象,造成不必要的阻塞。按说基于这个原因,微软应该提醒开发者尽量不要lock string对象,因为你不知道会不会刚好另外有一个对象与这个相同。假如一个组件中lock了一个"ABCD"的字符串,并且lock中做了一个耗时处理,那么假如外界又刚好也lock "ABCD",执行过程中外界的lock如果碰到组件中的lock块正在执行,那么得等组件中的lock块执行完才能执行下去,这显然是不必要的,并且外界不知道组件内发生的事情,所以此问题很难发现。若出现相互等待,那就更遭了。