锁定对象和所有子对象
Locking an object and all child objects
在 jim-mischel 关于实现线程安全树的 this answer 中,他指出:
The easiest way to do this would be to protect the entire tree with a ReaderWriterLockSlim. That allows concurrent access by multiple readers or exclusive access by a single writer. Any method that will modify the structure in any way will have to acquire the write lock, and no other threads will be allowed to read or write to the structure until that thread releases the write lock.
如果我没看错,这意味着树结构的 methods/properties 看起来像:
public class TreeNode
{
private String BackingData = "";
public String Data
{
get
{
lock (LockObject)
return BackingData;
}
set
{
lock (LockObject)
BackingData = value;
}
}
private TreeNode BackingParent { get; set; }
public TreeNode Parent
{
get
{
lock (LockObject)
return BackingParent;
}
}
//etc...
private List<TreeNode> BackingChildren { get; }
private Object LockObject { get; }
TreeNode()
{
BackingData = "";
BackingParent = null;
BackingChildren = new List<TreeNode>();
LockObject = new Object();
}
}
问题是,这并没有保护整棵树——它甚至没有保护树的单个节点,即使那样也只有单个 methods/properties。
如何布置才能保护整棵树?
我确实考虑过持有一个将根 TreeNodes 映射到对象的静态 class。然后,在这个静态 class 中有几个方法使用 Monitor 方法根据根 TreeNode 锁定和解锁。 Monitor.IsEntered 方法可以在 TreeNode 中使用,但要检查它是否已锁定,我们仍然需要沿着未锁定的树向上移动以获得根 TreeNode。即使那样,如果 IsEntered 为假,我也不知道如何处理。
是否有任何合适的方法来锁定一个对象,从而锁定该对象可能拥有的所有子对象?
保护共享树节点引用的最简单方法是锁定全局共享的私有变量。这将使您到达线程安全方面需要到达的位置。这不是最有效的解决方案,因为整棵树都被锁定了,但我怀疑它会引起任何问题。
因此,每当您的任何函数触及全局根节点时,请确保您
lock(mutex)
{
_root.Parent.Data = "Modified";
}
这将确保一次允许一个线程进入。
在 jim-mischel 关于实现线程安全树的 this answer 中,他指出:
The easiest way to do this would be to protect the entire tree with a ReaderWriterLockSlim. That allows concurrent access by multiple readers or exclusive access by a single writer. Any method that will modify the structure in any way will have to acquire the write lock, and no other threads will be allowed to read or write to the structure until that thread releases the write lock.
如果我没看错,这意味着树结构的 methods/properties 看起来像:
public class TreeNode
{
private String BackingData = "";
public String Data
{
get
{
lock (LockObject)
return BackingData;
}
set
{
lock (LockObject)
BackingData = value;
}
}
private TreeNode BackingParent { get; set; }
public TreeNode Parent
{
get
{
lock (LockObject)
return BackingParent;
}
}
//etc...
private List<TreeNode> BackingChildren { get; }
private Object LockObject { get; }
TreeNode()
{
BackingData = "";
BackingParent = null;
BackingChildren = new List<TreeNode>();
LockObject = new Object();
}
}
问题是,这并没有保护整棵树——它甚至没有保护树的单个节点,即使那样也只有单个 methods/properties。
如何布置才能保护整棵树?
我确实考虑过持有一个将根 TreeNodes 映射到对象的静态 class。然后,在这个静态 class 中有几个方法使用 Monitor 方法根据根 TreeNode 锁定和解锁。 Monitor.IsEntered 方法可以在 TreeNode 中使用,但要检查它是否已锁定,我们仍然需要沿着未锁定的树向上移动以获得根 TreeNode。即使那样,如果 IsEntered 为假,我也不知道如何处理。
是否有任何合适的方法来锁定一个对象,从而锁定该对象可能拥有的所有子对象?
保护共享树节点引用的最简单方法是锁定全局共享的私有变量。这将使您到达线程安全方面需要到达的位置。这不是最有效的解决方案,因为整棵树都被锁定了,但我怀疑它会引起任何问题。
因此,每当您的任何函数触及全局根节点时,请确保您
lock(mutex)
{
_root.Parent.Data = "Modified";
}
这将确保一次允许一个线程进入。