作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个名为 DataStorage 的单例对象,用于在我的应用程序中存储常用数据;其中之一是名为 myTable 的数据表,它将由多个线程读取和写入。我有一个私有(private)对象用作 DataStorage 中的锁,即
private object lockObj = new object();
我在访问 myTable 时使用了锁:
private DataTable myTable;
public DataTable MyTable
{
get
{ lock(lockObj) { return myTable; } }
set
{ lock(lockObj) { myTable = value; } }
}
另一个对象,即 MyObj 将获取此数据表,对其执行 Select,然后修改从 Select 检索到的 DataRow[] 中的某些值。我读到 Select 不是线程安全的,所以我这样写代码:
// lock on MyTable
DataTable dt = DataStorage.Instance.MyTable;
lock (MyObjLockObj) // lock object for MyObj class
{
// do a select, then modify value in the returned row
DataRow[] foundRows = dt.Select("some expression");
foundRows[0]["some col"] = 123456;
}
问题:1. 总的来说,这段代码是线程安全的吗?
当我在 MyObj 中修改检索到的 DataRow 时,MyTable setter 是否确保其线程安全?因为 setter 是设置 DataTable,而不是 DataRow。
我是否应该将访问 DataStorage.Instance.MyTable 的代码移动到与 Select 相同的锁 block 中?
提前致谢。
最佳答案
你的代码不是线程安全的,因为:
属性上的锁只能确保多个线程不能同时使用 get/set 属性,但在他们获得访问权限后可以同时更改它。
即
线程可以使用MyTable
属性来获取数据表的实例。之后,另一个线程可以使用该属性来获取相同的实例。然后在他们都可以访问 myTable
之后,他们都可以直接写入它而无需同步。
因此将访问器(accessor)移入锁中也无济于事。
最好提供更改数据的方法,并在这些方法中进行同步,而不是直接公开数据表。
关于C#:数据表线程安全问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6006827/
我是一名优秀的程序员,十分优秀!