从不同线程锁定方法范围的"字符串"对象阻止执行?

Jac*_*ack 4 c# multithreading locking

我刚刚在今天早上对多线程锁定进行了一些随机测试,奇怪的是我发现在两个单独的实例中锁定一个私有"字符串"实际上会阻止另一个线程执行.请在下面找到代码以供参考.

令我困惑的是两个对象中的"字符串"实际上是两个独立的对象,那么为什么锁定一个阻止另一个呢?(注意,如果用其他引用类型对象替换字符串,如List,它不会阻止其他线程执行,这实际上是我们所期望的......)

class Program {
    static void Main(string[] args) {
        Thread th = new Thread(DoWork);
        th.Start();

        Thread th2 = new Thread(DoWork);
        th2.Start();
    }

    static void DoWork() {
        Test importer = new Test();
        importer.SyncTest();
    }



}

public class Test {
    public void SyncTest() {
        string find = "test";
        lock(find) {                
            Console.WriteLine("thread starting...");
            Thread.Sleep(4000);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Kir*_*oll 6

字符串常量是"实习".这意味着当您键入时:

var s1 = "foo";
var s2 = "foo";
Run Code Online (Sandbox Code Playgroud)

两者都是字符串"foo" 的相同实例.同样,当您从不同的线程调用两次具有类似定义的局部变量的方法时,它是相同的实例.这是出于性能原因而完成的.

这是一种特殊情况,但另一方面,你真的不应该锁定字符串.(我还没有看到创建一个新的锁对象的idomatic解决方案不是要走的路的情况 - private object lockObject = new object();)

  • 用于创建新的私有对象以进行锁定的+1 - 这是唯一可行的方法 (2认同)