c# - 锁定来自不同线程的方法范围的 "string"对象会阻止执行吗?

标签 c# multithreading locking

今天早上我只是在多线程中做一些关于锁定的随机测试,奇怪的是我发现在两个单独的实例中锁定一个私有(private)“字符串”实际上会阻止另一个线程执行。请找到下面的代码以供引用。

让我感到困惑的是,两个对象中的“字符串”实际上是两个独立的对象,那么为什么锁定一个对象会阻塞另一个对象呢? (注意,如果你把string换成其他引用类型的对象,比如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);
        }
    }
}

最佳答案

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

var s1 = "foo";
var s2 = "foo";

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

这是一种特殊情况,但另一方面,您真的不应该锁定字符串。 (我还没有看到创建新锁对象的惯用解决方案不是可行的方法 -- private object lockObject = new object();)

关于c# - 锁定来自不同线程的方法范围的 "string"对象会阻止执行吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11149224/

相关文章:

c# - 如何在 RDLC 报告的同一文本框中左对齐和右对齐两个不同的表达式?

python - python中ThreadPool中每个线程的超时

java - 线程间共享数据和强制锁

java - RuleBasedCollat​​or 中的监控锁?

java - 寻找一种在没有数据库的情况下填充类的设计模式

c# - 在 Xamarin 中获取 Android 联系人

c# - PrintVisual 打印空页

C# 进程 - 完成前暂停或 sleep

c# - 如果我知道 API 在某个时候执行 I/O,我是否应该异步调用 brownfield API?

mysql - 选择共享模式锁定