我有一个方法,接受一个字符串入参,方法会被并发调用,我想在传入相同字符串的调用间上锁,比如有两个线程同时传入"abc"调用该方法,那我希望他们不能同时进入,需等一个完成另一个才进入。与此同时,另一个线程传入"xyz"的调用则不受影响。所以我应该锁什么?
void Foo(string s) {
lock(what) { } // ???
}
我现在锁的是String.Intern(s)
,但了解到这样会增加不可回收的驻留字符串,而这个方法在程序运行期间是会被传入无数不同的字符串调用无数次的,所以驻留下来的字符串会很可观,所以我想改进。
求支招,谢谢!
好像在内核看到过一个类似问题的解决方案:把字符串哈希到固定数量的桶,每个桶一把锁。
同一个桶里的不同串确实会互相影响,但是根据问题的具体情况可以调整桶数,让冲突的概率降低。
桶里可以有很多串,只要两个不同的串同时需要锁的概率够低就可以。加锁的持续时间越长,冲突可能性就越大。