[英]Is this class threadsafe?
这个ValueStore类线程是否安全? GetInt(字符串键)中的锁定范围是否需要在yield return周围扩展?
public class ValueStore
{
private readonly object _locker = new object();
private readonly Dictionary<string, int> _data =
new Dictionary<string, int>();
public ValueStore(Dictionary<string, int> data)
{
_data = data;
}
public IEnumerable<int> GetInt(string key)
{
IEnumerable<KeyValuePair<string, int>> selected;
lock(_locker)
{
selected = _data.Where(x => x.Key.Equals(key));
}
foreach (KeyValuePair<string, int> pair in selected)
{
yield return pair.Value;
}
}
}
单元测试似乎很好:
[TestFixture]
public class ValueStoreTest
{
[Test]
public void test1()
{
Dictionary<string, int> data = new Dictionary<string, int>();
for (int i = 0; i < 100000; i++)
{
data.Add(i.ToString(),i);
}
ValueStore vs = new ValueStore(data);
for (int i = 0; i < 900000; i++)
{
ThreadPool.QueueUserWorkItem(delegate
{
for (int j = 0; j < 100000; j++)
{
IEnumerable<int> d = vs.GetInt(j.ToString());
}
});
}
}
}
不,它绝对不是线程安全的。
它使用客户端传入的字典这一事实意味着您无法控制客户端何时更改它。 您也只是在应用Where
子句时锁定它 - 但实际上根本不执行任何迭代。 在迭代结果时你需要保持锁定 - 但正如我之前所说,它不会阻止客户端随时更改字典。
如果你在类中创建了字典并且只暴露了它中的数据(即保护它不受外界影响),你可以使它完全是线程安全的。 如果您坚持客户端代码不会改变字典,则根本不需要锁定,因为当没有编写器时,字典可以安全地从多个线程读取。
我可以告诉你,锁定中的语句直到锁定释放后才会执行。 如果必须在迭代期间锁定集合,则将yield移动到lock语句中。
不它不是。 如果您开始读取并写入您传递给构造函数的Dictionary<string, int>
对象,则会出现问题。 您的_data
类声明会立即被构造函数中的赋值覆盖。
要更正此问题,请将构造函数中传入的Dictionary
中的每个键/值对复制到类Dictionary
而不是直接赋值。
然后,我认为你是线程安全的,但显然你的类是只读的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.